• Stars
    star
    657
  • Rank 68,589 (Top 2 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 7 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Seamlessly use TypeScript with React Native

react-native-typescript-transformer

Seamlessly use TypeScript with react-native >= 0.45

Stop! You probably don't need this package.

If you are starting a new React Native project, you can follow the instructions in the React Native docs: https://facebook.github.io/react-native/docs/typescript

This will set up the project to transpile your TypeScript files using Babel.

Otherwise, if you're using React Native 0.57+ and you are converting an existing RN app to TS, then you can follow the configuration in this gist: https://gist.github.com/DimitryDushkin/bcf5a7f5df71113c67dbe2e890008308

Babel Caveats

Babel will not type-check your files. You'll still want to use the TypeScript compiler as a kind of linter (with the noEmit compiler option set to true).

Also there are four rarely-used langauge features that can't be compiled with Babel.

From this blog post:

  • namespaces
  • bracket style type-assertion/cast syntax regardless of when JSX is enabled (i.e. writing <Foo>x won’t work even in .ts files if JSX support is turned on, but you can instead write x as Foo).
  • enums that span multiple declarations (i.e. enum merging)
  • legacy-style import/export syntax (i.e. import foo = require(...) and export = foo)

Don't expect this list to grow.

I'm on RN < 0.57 or I definitely want to compile my TypeScript files using TypeScript and not Babel

Step 1: Install

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

Step 2: Configure TypeScript

Make sure your tsconfig.json has these compiler options:

{
  "compilerOptions": {
    "target": "es2015",
    "jsx": "react",
    "noEmit": true,
    "moduleResolution": "node",
  },
  "exclude": [
    "node_modules",
  ],
}

See tsconfig.json Notes for more advanced configuration details.

Step 3: Configure the react native packager

RN >= 0.59

In your projects root, extend metro.config.js so it contains the transformer.babelTransformerPath property:

module.exports = {
  transformer: {
    babelTransformerPath: require.resolve('react-native-typescript-transformer')
  }
};

RN >= 0.57, < 0.59

Add this to your rn-cli.config.js (make one if you don't have one already):

module.exports = {
  transformer: {
    babelTransformerPath: require.resolve('react-native-typescript-transformer')
  }
}

RN < 0.57

Add this to your rn-cli.config.js (make one if you don't have one already):

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

If you need to run the packager directly from the command line, run the following

react-native start --config /absolute/path/to/rn-cli.config.js

Step 4: Write TypeScript code!

Note that the platform-specific index files (index.ios.js, index.android.js, etc) still need to be .js files, but everything else can be TypeScript.

You probably want typings for react and react-native

yarn add --dev @types/react @types/react-native

Note that if you run yarn tsc it will act as a type checker rather than a compiler. Run it with --watch to catch dev-time errors in all files, not just the one you're editing.

Use tslib (Optional)

yarn add tslib

in tsconfig.json

 {
   "compilerOptions": {
+    "importHelpers": true,
   }
 }

Doing this should reduce your bundle size. See this blog post for more details.

Use absolute paths (Optional)

Absolute paths needs to have support from both the TypeScript compiler and the react-native packager.

This section will show you how to work with project structures like this:

<rootDir>
β”œβ”€β”€ src
β”‚Β Β  β”œβ”€β”€ package.json
β”‚Β Β  β”œβ”€β”€ App.tsx
β”‚Β Β  β”œβ”€β”€ components
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ Banana.tsx
β”‚Β Β  β”œβ”€β”€ index.tsx
β”œβ”€β”€ index.ios.js
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json

Where you want to be able to import Banana from 'src/components/Banana' from any .ts(x) file, regardless of its place in the directory tree.

TypeScript

In tsconfig.json:

 {
   "compilerOptions": {
+    "baseUrl": "."
   }
 }

react-native

For react-native you need to add one or more package.json files. These only need to contain the "name" field, and should be placed into any folders in the root of your project that you want to reference with an absolute path. The "name" field's value should be the name of the folder. So for me, I just added one file at src/package.json with the contents {"name": "src"}.

Jest (Optional)

If you use Jest as a test runner, add the following in your root package.json:

 {
   "jest" {
+     "modulePaths": ["<rootDir>"]
   }
 }

tsconfig.json Notes

  • If you enable synthetic default imports with the "allowSyntheticDefaultImports" flag, be sure to set "module" to something like "es2015" to allow the es6 import/export syntax to pass through the TypeScript compiler untouched. Then Babel can compile those statements while emitting the necessary extra code to make synthetic default imports work properly.

    This is neccessary until TypeScript implements suport for synthetic default imports in emitted code as well as in the type checker. See Microsoft/TypeScript#9562.

  • "target" can be anything supported by your project's Babel configuration.

  • "jsx" can also be "react-native" or "preserve", which are functionally identical in the context of a react-native-typescript-transformer project. In this case, the JSX syntax is compiled by Babel instead of TypeScript

  • The source map options are not useful

  • You probably want to specify some base typings with the "lib" option. I've had success with the following:

     {
       "compilerOptions": {
    +    "lib": [ "es2017" ],
       }
     }

    Including the "dom" lib is not recommended. The React Native JavaScript runtime does not include any DOM-related APIs. See JavaScript Environment for more details on what web APIs React Native supports.

Jest notes

Follow the react-native setup guide for ts-jest.

Alternatively, if you want to use exactly the same transformation code for both Jest and react-native check out this comment.

Note that there have been no reports of problems arising from differences between code compiled by the ts-jest transformer and code compiled by react-native-typescript-transformer. Additionally, ts-jest takes care of a lot of edge cases and is more configurable.

Avoid cyclical dependencies

If you're transitioning an app from tsc to react-native-typescript-transformer, you might see runtime errors which involve imported modules being undefined. You almost certainly have cyclical inter-module dependencies which manifest during your app's initialization. e.g. if ModuleA is undefined in ModuleB it means that ModuleA (in)directly imports ModuleB.

tsc seems to be able to mitigate some instances of these cyclical dependencies when used as a whole-app compiler. Unfortunately the module-at-a-time compilation approach that react-native's bundler supports does not permit the same optimizations.

Be especially careful of "umbrella export" files which can easily introduce these cycles.

License

MIT

Empowered by Futurice's open source sponsorship program

More Repositories

1

patch-package

Fix broken node modules instantly πŸƒπŸ½β€β™€οΈπŸ’¨
TypeScript
10,288
star
2

lazyrepo

Caching task runner for npm/pnpm/yarn monorepos.
TypeScript
528
star
3

derivablejs

Functional Reactive State for JavaScript and TypeScript
JavaScript
515
star
4

jetzt

Speed reader extension for chrome
JavaScript
486
star
5

postinstall-postinstall

JavaScript
53
star
6

android-capture

Capture video and screenshots from Android devices and emulators.
JavaScript
34
star
7

code-in-motion

JavaScript
17
star
8

cfg

Option management for Clojure
Clojure
11
star
9

ddom

derivable dom
JavaScript
11
star
10

redux-mobx-connect

A simple alternative to react-redux
TypeScript
9
star
11

gudetama

Make your CI scripts as lazy as possible
TypeScript
7
star
12

prismic-react

Compiling Prismic.io content to ReactElements
JavaScript
5
star
13

lunch-time

TypeScript
5
star
14

apt

Anchored Packed Trees for compositional distributional semantics
Java
3
star
15

artsy-nonlocality

Chrome extension for artsy employees to launch zoom meetings more easily
TypeScript
3
star
16

patch-package-website-design

figma file for unused patch-package website design
3
star
17

derivables-talk-demo

Code demonstration of Derivables from my talk
JavaScript
2
star
18

rn-back

dual n-back in react native
JavaScript
2
star
19

postinstall-prepare

JavaScript
2
star
20

kfs

TypeScript
2
star
21

encrypt-and-decrypt

TypeScript
2
star
22

atom-gitnav

move forward and backward through git history with hotkeys
CoffeeScript
1
star
23

mental

super simple mental arithmetic game
JavaScript
1
star
24

loggy

dumb irc room logger
Go
1
star
25

norm

A suite of tools coalescing into a lexical normalisation system for tweets.
Clojure
1
star
26

TestCustomSourceExts

Objective-C
1
star
27

apt-py

python api for reading and manipulating APTs
Python
1
star
28

vimes

oh lisp
TypeScript
1
star
29

sicp

going through sicp in emacs
Scheme
1
star
30

nlp-trie

Immutable trie implementation for Clojure. Uses string keys. Optimised for lookups and traversal.
Clojure
1
star
31

gridster

JavaScript
1
star
32

FlowDoge

wow such flow
TypeScript
1
star