New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript support using Babel 7 #4837

Merged
merged 1 commit into from Oct 21, 2018

Conversation

@brunolemos
Collaborator

brunolemos commented Jul 29, 2018

Adds TypeScript support.

Closes #4146
Closes #2815

The user can just rename .js to .tsx and it will work.

To enable type checking, the user needs to create a tsconfig.json file at the root directory and install the typescript fork-ts-checker-webpack-plugin dependencies. It will appear at the same console as the build one. Another option is to install only typescript and run npx tsc -w on a new terminal tab instead.

Includes

  • Support .ts and .tsx file extensions
  • Support type checking using fork-ts-checker-webpack-plugin (opt in)
  • Support media imports json, bmp, gif, jpeg, jpg, png and svg
  • Support typescript option on react-app babel preset to enable/disable @babel/preset-typescript (enabled by default, just like flow)
  • Update docs
  • Basic test

These items were included, but removed per review suggestion

  • TSLint support using fork-ts-checker-webpack-plugin (#4837 (comment), #4837 (comment))
  • ESLint support for TypeScript files using typescript-eslint-parser (#4837 (comment))
  • Support tsconfig.prod.json and tslint.prod.json (#4837 (comment))
  • Automatically enable flow or typescript presets by detecting .flowconfig and tsconfig.json
  • Prevent enabling both flow and typescript in the same project

Pending suggestions (help wanted!)

  • Fix build test not passing even though it's correct (#5440)
  • Add more advanced tests
  • Use async: true on type checking? (would need to fix errors not showing up) (it's ok for this first iteration)
  • Make sure ESLint works great on tsx files
  • Make sure there are no conflicts between typescript preset and flow plugin because both are being enabled together by default (none were found or reported by now)
  • Automatically generate a tsconfig.json when typescript is imported for the first time?
  • Check and force some tsconfig.json options like isolatedModules: true?
  • Remove typescript dependency? (will probably need to change something on fork-ts-checker-webpack-plugin, because it isn't working without it)
  • Re-run type checking after changing files that webpack is not watching? (#4837 (comment))
  • Enable type checking on test files using ts-jest? (#4837 (comment)) (no)

Screenshot

type TestType = 'a' | 'b'
const x: TestType = 123

image

How to try this PR while it's not merged

  • Clone
    • git clone git@github.com:brunolemos/create-react-app.git
    • cd create-react-app
    • git checkout next-typescript
  • Compile
    • yarn
  • Create Link
    • cd packages/react-scripts/
    • yarn link
  • Create New Project
    • cd ~/your/projects/folder
    • npx create-react-app app-name
    • cd app-name
  • Use Link
    • yarn link react-scripts
  • Setup TypeScript
  • Finish
    • yarn start
    • Have fun with types 馃帀
@ianschmitz

This comment has been minimized.

Collaborator

ianschmitz commented Jul 30, 2018

One way to fix image imports TS error:

https://github.com/wmonk/create-react-app-typescript/blob/e4b1f9424fa14f7aae7f0cbf5fd64e18dd273527/packages/react-scripts/template/images.d.ts

However this doesn't take into account the recent improvements made in CRA 2.0 such as #3718

@brunolemos

This comment has been minimized.

Collaborator

brunolemos commented Jul 30, 2018

@iainbeeston thanks! I added an index.d.ts file fixing jpg, png and svg.
It also includes typings for the svg ReactComponent.

We currently only have one template folder so this way the index.d.ts will be available on non-typescript projects as well, not sure if that's a problem. Maybe it's a good thing, because it adds autocomplete to js projects as well.

@@ -0,0 +1,12 @@
declare module '*.jpg'

This comment has been minimized.

@frankwallis

frankwallis Aug 13, 2018

I don't think this file should be called index.d.ts as this name will conflict with the automatically generated typings file for index.ts. In my projects I normally call this file externals.d.ts or similar but I don't really mind what it is called.

declare module '*.png'
declare module '*.svg' {
import * as React from 'react'

This comment has been minimized.

@frankwallis

frankwallis Aug 13, 2018

To be consistent with index.js this should be import React from 'react'. This does assume that esModuleInterop: true is specified in tsconfig.json but I think this is best practice for new projects as it means that typescript and babel are more closely aligned.

declare module '*.svg' {
import * as React from 'react'
export const ReactComponent: React.SFC<React.SVGProps<SVGSVGElement>>

This comment has been minimized.

@frankwallis

frankwallis Aug 13, 2018

I'm interested to know why this is needed?

@@ -1,5 +1,7 @@
import 'jest';

This comment has been minimized.

@frankwallis

frankwallis Aug 13, 2018

An alternative to adding this import is to add types: [ 'jest' ] to tsconfig.json

This comment has been minimized.

@ianschmitz

ianschmitz Aug 13, 2018

Collaborator

I don't believe either should be needed. Typescript should pick up the node_modules/@types definitions automatically without any extra effort.

```json
{
"compilerOptions": {
"target": "ESNEXT",

This comment has been minimized.

@frankwallis

frankwallis Aug 13, 2018

nit: capitalization

@frankwallis

This comment has been minimized.

frankwallis commented Aug 13, 2018

This is awesome - it will be fantastic to finally have first class support for typescript :)
I have added a few comments, but great work!

@@ -0,0 +1,12 @@
declare module '*.jpg'
declare module '*.png'

This comment has been minimized.

@frankwallis

frankwallis Aug 13, 2018

declare module '*.png' {
  const src: string
  export default src
}

Is more accurate here as webpack url/file-loader will export the string path of the png file

@frankwallis

This comment has been minimized.

frankwallis commented Aug 13, 2018

What is the easiest way to try this out please?

@brunolemos

This comment has been minimized.

Collaborator

brunolemos commented Aug 13, 2018

This is awesome - it will be fantastic to finally have first class support for typescript :)
What is the easiest way to try this out please?

@frankwallis thanks for reviewing! Please check the instructions in the first comment to try it out

Show resolved Hide resolved packages/react-scripts/template/README.md Outdated

@prichodko prichodko referenced this pull request Sep 7, 2018

Closed

Add TypeScript support #1

@borisowsky

This comment has been minimized.

borisowsky commented Sep 8, 2018

So what about tsconfig-s aliases? (compilerOptions -> paths). It should be working with webpack aliases (auto-injected?).

@RIP21

This comment has been minimized.

RIP21 commented Sep 9, 2018

In instructions, it says that you need to rename all js files with ts is it really needed or interoperability is possible?

@RIP21

This comment has been minimized.

RIP21 commented Sep 9, 2018

Also, setupTests.ts is not supported. It's still looking for setupTests.js when tsconfig.json is present which I think is wrong.
Both should be supported as well as the mixed project at all. JS and TS I mean.

@@ -90,7 +90,11 @@ checkBrowsers(paths.appPath)
);
console.log(
'To ignore, add ' +
chalk.cyan('// eslint-disable-next-line') +
chalk.cyan(
paths.isTypeScript

This comment has been minimized.

@GabrielDuarteM

GabrielDuarteM Sep 10, 2018

I think we shouldn't assume that if typescript is being used, tslint will necessarily be used too. Eslint can be used with typescript, using typescript-eslint-parser and eslint-plugin-typescript.

Maybe putting a isTslint inside the paths (checking the presence of a tslint.json), and using that to determine the message would be more reliable...

@brunolemos

This comment has been minimized.

Collaborator

brunolemos commented Sep 10, 2018

Thanks for the suggestions, I'll wait until a core maintainer manifests about this pull request

@RIP21

This comment has been minimized.

RIP21 commented Sep 10, 2018

For whom it may concern. Interop with JS is possible. For simple project works nicely (I fixed setupTests.ts thing tho manually)

@bensleveritt

This comment has been minimized.

bensleveritt commented Sep 10, 2018

@brunolemos It'd be good to get your react-scripts package published somewhere. Trying to use it, but can't link in a CI system means we can't use it in serious development. Even a proxy package would be good until this is integrated.

@nhducit

This comment has been minimized.

nhducit commented Sep 10, 2018

@bensleveritt I think you can pull @brunolemos branch to your machine then use yarn link to use it.

@DanielRosenwasser

This comment has been minimized.

DanielRosenwasser commented Oct 19, 2018

@Serguzest can you give an example of what scenario you have in mind here?

@Serguzest

This comment has been minimized.

Serguzest commented Oct 19, 2018

@Serguzest can you give an example of what scenario you have in mind here?

@DanielRosenwasser

src/models.ts

interface user {
  name: string;
}

src/someDirectory/someOtherFile.tsx

import * as React from "react";

//I don't need to explicitly import "user" type to able to use it in here
const user: user = {
  name: "ahmet"
};
@samuelcastro

This comment has been minimized.

samuelcastro commented Oct 19, 2018

Any thoughts when are we going to get this through?

@samuelcastro

This comment has been minimized.

samuelcastro commented Oct 19, 2018

@brunolemos I saw that these items were removed:

  • TSLint support using fork-ts-checker-webpack-plugin
  • ESLint support for TypeScript files using typescript-eslint-parser

Any reasons why? Which one should we use, would tslint make more sense since it's typescript? And last, how to use it with tslint?

@brunolemos

This comment has been minimized.

Collaborator

brunolemos commented Oct 20, 2018

@samuelcastro: I saw that these items were removed, any reasons why?

TL/DR, ESLint was not enabled on ts files because it requires typescript-eslint-parser which is still not mature and has a big Help Wanted! banner in the readme, which could cause maintainability issues for the CRA team. It also targets specific versions of typescript which could prevent users from upgrading. (#4837 (comment), #4837 (comment))

TSLint built-in support was removed because CRA itself does not lint style preferences, but only critical things like undeclared variable names and typescript already has good defaults for this. Also, the user can run tslint on their own with no problem. (#4837 (comment))

@stunaz

This comment has been minimized.

stunaz commented Oct 20, 2018

Great! Now what? Release, shall we?

@Timer Timer merged commit 88aef11 into facebook:master Oct 21, 2018

1 of 2 checks passed

continuous-integration/appveyor/pr AppVeyor build failed
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@alexdor

This comment has been minimized.

alexdor commented Oct 21, 2018

Huge thanks to @brunolemos for all his effort and of course huge thanks to the team of create react app : ) Can't wait for this to be released : )

@brunolemos

This comment has been minimized.

Collaborator

brunolemos commented Oct 21, 2018

IT'S MERGED 馃帀馃帀馃帀
Thanks everyone for the motivation and reviews, and thanks @Timer for merging!

EDIT: Just tweeted about it

馃挋

@RIP21

This comment has been minimized.

RIP21 commented Oct 21, 2018

Amazing stuff! :) Finally :)

@noahjohn9259

This comment has been minimized.

noahjohn9259 commented Oct 22, 2018

Many thanks to @brunolemos for your efforts.. Looking forward for the release :)

@johnnyreilly

This comment has been minimized.

johnnyreilly commented Oct 22, 2018

I'm so happy this has merged!

A future improvement could be strongly typed JSON support by setting this option in tsconfig.json:

	"resolveJsonModule": true

@kdnk kdnk referenced this pull request Oct 22, 2018

Closed

[Public] Frontend Night #23 #23

danielmahon added a commit to danielmahon/create-react-app that referenced this pull request Oct 22, 2018

@eps1lon eps1lon referenced this pull request Oct 22, 2018

Open

[docs] Demos in TypeScript #13229

2 of 5 tasks complete

@ianschmitz ianschmitz referenced this pull request Oct 22, 2018

Closed

[WIP] TypeScript final touches #5514

0 of 3 tasks complete
@veeral-patel

This comment has been minimized.

veeral-patel commented Oct 22, 2018

Awesome. Thank you!

@facebook facebook locked as resolved and limited conversation to collaborators Oct 23, 2018

@Timer

This comment has been minimized.

Collaborator

Timer commented Oct 23, 2018

I've locked this PR since it's high profile and to keep notification spam low. We'll post updates here when we have them.

Please file any concerns as new issues, thanks!

@brunolemos brunolemos deleted the brunolemos:next-typescript branch Oct 23, 2018

@Timer

This comment has been minimized.

Collaborator

Timer commented Oct 30, 2018

TypeScript is now officially supported as of Create React App 2.1. Read the release notes to get started!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.