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 to babel-preset-react-app
- Use the filename extension of
paths.appIndexJs to determine whether to set the useTypeScript 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 and tslint.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 with eslint-config-react-app
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 (or yarn add typescript @types/react @types/react-dom).
- Add
"type-check": "tsc" to the scripts section of your package.json.
- Add a
"resolutions" section to your package.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 to src/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.
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.jstosrc/index.tsx.Suggested Solution
paths.appIndexJs(i.e.src/index.js->src/index) so it works regardless of.jsor.tsor.tsx..tsand.tsxto the extensions in webpack config (resolve, babel loader, file-loader) and Jest configuseTypescriptflag (so that this choice is explicit) and related@babel/preset-typescriptpackage tobabel-preset-react-apppaths.appIndexJsto determine whether to set theuseTypeScriptflag in webpack babel-loader options and jest babel transformationAreas of Interest/Discussion/Questions
tsconfig.jsonandtslint.jsonbe zero config? (probably not)fork-ts-webpack-plugin? (my vote is against this)tslint-loaderto Webpack config if in "TS mode"eslint-loaderwith Babel 7 TS? (I'm not sure)tslint-config-react-apppackage that is congruent witheslint-config-react-appSuggested 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:
npm install --save typescript @types/react @types/react-dom(oryarn add typescript @types/react @types/react-dom)."type-check": "tsc"to the scripts section of yourpackage.json."resolutions"section to yourpackage.jsonto avoid conflicting types of React and ReactDOM in your dependencies:tsconfig.jsonin 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. } }src/index.jstosrc/index.tsxNow you can run
npm run type-check(oryarn 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.