Skip to content

TypeScript: Set "target": "es6" (or lib: ["es2018"]) in default tsconfig.json to avoid a lot of confusion #5771

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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ndbroadbent opened this issue Nov 11, 2018 · 2 comments

Comments

@ndbroadbent
Copy link

ndbroadbent commented Nov 11, 2018

Hello, thanks for working on this awesome project! I've been trying to get everything working with TypeScript, and I just went down a huge rabbit hole before realizing that I had completely misunderstood how everything worked. (It's my first time using TypeScript, as well as all the bleeding edge versions for create-react-app, webpack, babel, etc.)

When I ran yarn start for the first time with an App.tsx, I got this message:

We detected TypeScript in your project (src/App.tsx) and created a tsconfig.json file for you.

The default tsconfig.json that it generates has this line:

"target": "es5",

I wanted to use Array.fill in my code (and Object.assign, etc.), and this was giving me a TypeScript error:

Type error: Property 'fill' does not exist on type 'string[]'.  TS2339

I started investigating the issue, and I saw that I could fix it by using "target": "es6" in my tsconfig.json. But then I was concerned that the JS output from webpack would be ES6, and I would lose support for older browsers. I saw that I could also use:

 target: "es5"
 lib: ["es2018"]

Then TypeScript would emit ES5, but it would use the es2018 type declarations for type-checking (and would just assume that I was including my own polyfills.) That sounded a bit better, but then I was worried that I would lose tree shaking if TypeScript emitted ES5 (because then it would have require statements instead of ES6 modules.)

I got very confused and was Googling things like "TypeScript vs Babel", and "TypeScript => ES6 => Babel => ES5", and there was no shortage of misleading answers and blog posts that were leading me down the wrong track.

I finally started reading through the react-scripts webpack config and babel-preset-react-app, and I found that create-react-app is 100% Babel for all of the JS compilation, and it doesn't use any TS loaders (like ts-loader or awesome-typescript-loader.) Babel just strips all of the TS types and doesn't care about them. I also realized that the webpack config was using ForkTsCheckerWebpackPlugin to run the TypeScript typechecking in a separate process, and then it asynchronously shows any TypeScript errors in the browser.

And then it finally clicked! Or at least, I think I get it... Please correct me if I'm wrong on any of these points:

  • Babel doesn't care about tsconfig.json at all. It just strips all the TypeScript types, so this has nothing to do with the webpack build.
  • TypeScript is actually only used for type-checking, and the type-checking step doesn't actually care about "target": "es5" either, because it's not emitting any JavaScript. However, it does infer the type definitions from the target, and these can be overridden with the "lib" option.
  • The create-react-app webpack config already uses babel/preset-env with a target of IE9, so it does already include polyfills for Object.assign, Array.from, etc.

So is it correct that the only thing I need to do to fix these TypeScript errors is to just set target: "es6" (or lib: ["es2018"]) in my tsconfig.json? If so, I think it would be good if this was the default target.

@ndbroadbent ndbroadbent changed the title Set "target": "es6" in tsconfig.json to avoid a lot of confusion Set "target": "es6" (or lib: ["es2018"]) in default tsconfig.json to avoid a lot of confusion Nov 11, 2018
@ndbroadbent ndbroadbent changed the title Set "target": "es6" (or lib: ["es2018"]) in default tsconfig.json to avoid a lot of confusion TypeScript: Set "target": "es6" (or lib: ["es2018"]) in default tsconfig.json to avoid a lot of confusion Nov 11, 2018
@ndbroadbent
Copy link
Author

I finally figured out where to update the default TypeScript target! Here's the PR that fixes this issue: #5772

@ndbroadbent
Copy link
Author

ndbroadbent commented Nov 11, 2018

Never mind, this was already fixed! #5684

I think it would be nice to release a new version so that other developers don't run into the same issue.

@lock lock bot locked and limited conversation to collaborators Jan 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant