RFC: Zero-config TypeScript with Babel 7
Created by: jaredpalmer
Zero-config TypeScript with Babel 7
As mentioned in several other issues, with the release of Babel 7 and CRA 2, TypeScript support is now possible in a way that does not dramatically change the core of CRA internals. Before proceeding with a PR, would love to gather feedback on a solution / implementation I came up with over the weekend:
Current Behavior
TypeScript users cannot use CRA directly. Popular alternatives include react-scripts-ts
(a fork of CRA that uses the TypeScript compiler) and Microsoft's React TypeScript boilerplate.
Desired Behavior
CRA works with TypeScript via Babel 7 with zero-config. To enable TypeScript, users can just rename src/index.js
to src/index.tsx
.
Suggested Solution
- Remove filename extension from
paths.appIndexJs
(i.e.src/index.js
->src/index
) so it works regardless of.js
or.ts
or.tsx
. - Add
.ts
and.tsx
to the extensions in webpack config (resolve, babel loader, file-loader) and Jest config - Add a
useTypescript
flag (so that this choice is explicit) and related@babel/preset-typescript
package tobabel-preset-react-app
- Use the filename extension of
paths.appIndexJs
to determine whether to set theuseTypeScript
flag in webpack babel-loader options and jest babel transformation - Add documentation about TypeScript usage
Areas of Interest/Discussion/Questions
- Alternative ways to determine whether to enable TS?
- Should
tsconfig.json
andtslint.json
be zero config? (probably not) - Should we add built-in type checking with
fork-ts-webpack-plugin
? (my vote is against this) - (bonus) Add
tslint-loader
to Webpack config if in "TS mode"- Question: can we use
eslint-loader
with Babel 7 TS? (I'm not sure) - If not, we should add a minimal
tslint-config-react-app
package that is congruent witheslint-config-react-app
- Question: can we use
Suggested Documentation
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. Check out this introduction to using static types in JavaScript if you are new to this concept.
Recent versions of TypeScript work with Create React App projects out of the box thanks to Babel 7. Babel 7 TypeScript does not allow some features of TypeScript such as constant enum and namespaces. You can read more about Babel TypeScript here.
To add TypeScript to a Create React App project, follow these steps:
- Run
npm install --save typescript @types/react @types/react-dom
(oryarn add typescript @types/react @types/react-dom
). - Add
"type-check": "tsc"
to the scripts section of yourpackage.json
. - Add a
"resolutions"
section to yourpackage.json
to avoid conflicting types of React and ReactDOM in your dependencies:
"resolutions": {
"**/@types/react": "16.0.40",
"**/@types/react-dom": "16.0.4"
},
- Create a file called
tsconfig.json
in the root of your project:
{
"compilerOptions": {
"target": "esnext", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"jsx": "react", /* Use React to interpret JSX */
"noEmit": true, /* Do not emit outputs. */
"allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export.
}
}
- Rename
src/index.js
tosrc/index.tsx
Now you can run npm run type-check
(or yarn type-check
) to check the files for type errors. You can optionally use an IDE like Nuclide or VSCode for a better integrated experience.
To learn more about TypeScript, check out its documentation.