Skip to content

RFC: Zero-config TypeScript with Babel 7 #4146

Closed
@jaredpalmer

Description

@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 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:

  • Runnpm 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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions