Skip to content

Latest commit

 

History

History
256 lines (193 loc) · 12.6 KB

MIGRATING.md

File metadata and controls

256 lines (193 loc) · 12.6 KB
react + ts logo

Cheatsheets for experienced React developers getting started with TypeScript

Basic | Advanced | Migrating | HOC | 中文翻译 | Español | Contribute! | Ask!


Migrating (to TypeScript) Cheatsheet

This Cheatsheet collates advice and utilities from real case studies of teams moving significant codebases from plain JS or Flow over to TypeScript. It makes no attempt to convince people to do so, but we do collect what few statistics companies offer up after their conversion experience.

⚠️ This Cheatsheet is extremely new and could use all the help we can get. Solid advice, results, and up to date content all welcome.

Prerequsite

Read TypeScript's official Guide for migrating from JS and you should already be familiar with their React conversion guide.

General Conversion approaches

  • Level 0: Don't use TypeScript, use JSDoc
  • Level 1A: Majority JavaScript, increasingly strict TypeScript
  • Level 1B: Total rename to TypeScript from the start
  • Level 2: Strict TypeScript
    • use Microsoft's dts-gen to generate .d.ts files for your untyped files. This SO answer has more on the topic.
    • use declare keyword for ambient declarations - see declaration merging to patch library declarations inline

Misc tips/approaches successful companies have taken

Webpack tips
  • webpack loader: awesome-typescript-loader vs ts-loader? (there is some disagreement in community about this - but read awesome's point of view)
  • Webpack config:
module.exports = {

resolve: {
-    extensions: ['.js', '.jsx']
+    extensions: ['.ts', '.tsx', '.js', '.jsx']
},

// Source maps support ('inline-source-map' also works)
devtool: 'source-map',

// Add the loader for .ts files.
module: {
  loaders: [{
-       test: /\.jsx?$/,
-       loader: 'babel-loader',
-       exclude: [/node_modules/],
+       test: /\.(t|j)sx?$/,
+       loader: ['awesome-typescript-loader?module=es6'],
+       exclude: [/node_modules/]
+   }, {
+       test: /\.js$/,
+       loader: 'source-map-loader',
+       enforce: 'pre'
  }]
}
};

Special note on ts-loader and 3rd party libraries: https://twitter.com/acemarke/status/1091150384184229888

JSDoc

Problems to be aware of:

  • object is converted to any for some reason.
  • If you have an error in the jsdoc, you get no warning/error. TS just silently doesn't type annotate the function.
  • casting can be verbose

(thanks Gil Tayar and Gleb Bahmutov for sharing above commentary)

From JS

Automated JS to TS Conversion

Manual JS to TS Conversion

the "Just Renaming" strategy

  • OSX/Linux: find src -name "*.js" -exec sh -c 'mv"$0" "${0%.js}.tsx"' {} \;

You can either load typescript files with webpack, or use the tsc compiler to compile your TS files to JS side by side. The basic tsconfig.json is:

{
  "compilerOptions": {
    "allowJs": true
  }
}

Then you will want to enable it to check JS:

{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": true
  }
}

If you have a large codebase and this throws too many errors at once, you can opt out problematic files with //@ts-nocheck, or instead turn off checkJs and add a //@ts-check directive at the top of each regular JS file.

TypeScript should throw up some egregious errors here which should be easy to fix.

Once you are done, swallow the red pill by turning off implicit any's:

{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": true,
    "noImplicitAny": true // or "strict": true
  }
}

This will raise a bunch of type errors and you can start converting files to TS or (optionally) use JSDoc annotations in your JS.

A common practice here is using an ambient TODO type alias for any so you can keep track of what you need to come back to:

type TODO_TYPEME = any;
export function myFunc(foo: TODO_TYPEME, bar: TODO_TYPEME): number {
  // ...
}

Gradually add more strict mode flags like noImplicitThis, strictNullChecks, and so on until you can eventually just run in full strict mode with no js files left:

{
  "compilerOptions": {
    "strict": true
  }
}

More resources

Old content that is possibly out of date

From Flow

Results

  • Number of production deploys doubled for Hootsuite
  • Found accidental globals for Tiny
  • Found incorrect function calls for Tiny
  • Found rarely used, buggy code that was untested for Tiny

Academic Studies of Migration

Our central finding is that both static type systems find an important percentage of public bugs: both Flow 0.30 and TypeScript 2.0 successfully detect 15%!

Misc migration stories by notable companies and open source

Open Source

Links