Easy TypeScript with React Native

Just here for the code sample? Check it out here.

Trying to combine TypeScript (TS) with React Native (RN) has historically been kind of difficult. It has been possible by employing some clever, but hacky, solutions. The problem is, that those solutions are difficult to maintain. And they might become more cumbersome with every RN release, since they are unsupported.

Using features which makes creating RN apps enjoyable, like Hot-Module Reloading (HMR), has also been a pain. Why this is may be a boring implementation detail. But suffice it to say, it has to do with the RN packager only watching js and json files. Updates to code files with other extensions do not trigger a reload.

Now though, with the forthcoming release of RN v0.45.0 you'll have a better alternative. A newly landed PR (by David Sheldrick) allows you to customise which extension the packager should watch.

The other piece of the puzzle, is that we need to compile TS down to JavaScript (JS) for the RN packager to pick up. Instead of doing this manually (either through tsc or hooking it up with npm scripts), we want this to happen automatically as part of a normal react-native start command.

RN already provides the ability to hook in your own transformer through react-native start --transformer ./path/to/transformer.js. But it turns out you can actually do one better by supplying your own rn-cli.config.js and defining it there.

And you won't even have to write your own transformer, since David comes to the rescue here again with his react-native-typescript-transfomer.

For simplity's sake I'll echo his installation instructions here. In your RN project folder, run:

yarn add --dev react-native-typescript-transformer typescript

Next, in your project root, create a rn-cli.config.js file, and add the following

module.exports = {
  getTransformModulePath() {
    return require.resolve('react-native-typescript-transformer')
  },
  getSourceExts() {
    return ['ts', 'tsx'];
  }
}

As you can see, here you're setting the transformer to use (so you can just run react-native start). You're also adding your custom source extensions which will (along with js and json) be picked up by the RN packager.

You'll also need a tsconfig.json file for the TS compiler with the following settings (in your project root):

{
  "compilerOptions": {
    "target": "es2015",
    "module": "es2015",
    "jsx": "react-native",
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true
  }
}

That should be all you need to get the RN packager to pick up your TS source files, and compile them automatically to JS.

This works with HMR, proper source maps and debugging, and everything else you come to expect from building an RN app!

To get you started on the actual coding, I've also made a simple Counter-app (starter) project with Redux: react-native-typescript-starter.