Version: next

Using TypeScript

TypeScript is a language which extends JavaScript by adding type definitions, much like Flow. While React Native is built in Flow, it supports both TypeScript and Flow by default.

Getting Started with TypeScript

If you're starting a new project, there are a few different ways to get started. You can use the TypeScript template:

npx react-native init MyApp --template react-native-template-typescript

Note: If the above command is failing, you may have old version of react-native or react-native-cli installed globally on your system. To fix the issue try uninstalling the CLI:

  • npm uninstall -g react-native-cli or yarn global remove react-native-cli

and then run the npx command again.

You can use Expo which has two TypeScript templates:

npm install -g expo-cli
expo init MyTSProject

Or you could use Ignite, which also has a TypeScript template:

npm install -g ignite-cli
ignite new MyTSProject

Adding TypeScript to an Existing Project

  1. Add TypeScript and the types for React Native and Jest to your project.
yarn add --dev typescript @types/jest @types/react @types/react-native @types/react-test-renderer
# or for npm
npm install --save-dev typescript @types/jest @types/react @types/react-native @types/react-test-renderer
  1. Add a TypeScript config file. Create a tsconfig.json in the root of your project:
{
"compilerOptions": {
"allowJs": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"isolatedModules": true,
"jsx": "react",
"lib": ["es6"],
"moduleResolution": "node",
"noEmit": true,
"strict": true,
"target": "esnext"
},
"exclude": [
"node_modules",
"babel.config.js",
"metro.config.js",
"jest.config.js"
]
}
  1. Create a jest.config.js file to configure Jest to use TypeScript
module.exports = {
preset: 'react-native',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node']
};
  1. Rename a JavaScript file to be *.tsx

You should leave the ./index.js entrypoint file as it is otherwise you may run into an issue when it comes to bundling a production build.

  1. Run yarn tsc to type-check your new TypeScript files.

How TypeScript and React Native works

Out of the box, transforming your files to JavaScript works via the same Babel infrastructure as a non-TypeScript React Native project. We recommend that you use the TypeScript compiler only for type checking. If you have existing TypeScript code being ported to React Native, there are one or two caveats to using Babel instead of TypeScript.

What does React Native + TypeScript look like

You can provide an interface for a React Component's Props and State via React.Component<Props, State> which will provide type-checking and editor auto-completing when working with that component in JSX.

// components/Hello.tsx
import React from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
export interface Props {
name: string;
enthusiasmLevel?: number;
}
const Hello: React.FC<Props> = (props) => {
const [enthusiasmLevel, setEnthusiasmLevel] = React.useState(
props.enthusiasmLevel
);
const onIncrement = () =>
setEnthusiasmLevel((enthusiasmLevel || 0) + 1);
const onDecrement = () =>
setEnthusiasmLevel((enthusiasmLevel || 0) - 1);
const getExclamationMarks = (numChars: number) =>
Array(numChars + 1).join('!');
return (
<View style={styles.root}>
<Text style={styles.greeting}>
Hello{' '}
{props.name + getExclamationMarks(enthusiasmLevel || 0)}
</Text>
<View style={styles.buttons}>
<View style={styles.button}>
<Button
title="-"
onPress={onDecrement}
accessibilityLabel="decrement"
color="red"
/>
</View>
<View style={styles.button}>
<Button
title="+"
onPress={onIncrement}
accessibilityLabel="increment"
color="blue"
/>
</View>
</View>
</View>
);
};
// styles
const styles = StyleSheet.create({
root: {
alignItems: 'center',
alignSelf: 'center'
},
buttons: {
flexDirection: 'row',
minHeight: 70,
alignItems: 'stretch',
alignSelf: 'center',
borderWidth: 5
},
button: {
flex: 1,
paddingVertical: 0
},
greeting: {
color: '#999',
fontWeight: 'bold'
}
});
export default Hello;

You can explore the syntax more in the TypeScript playground.

Where to Find Useful Advice

Using Custom Path Aliases with TypeScript

To use custom path aliases with TypeScript, you need to set the path aliases to work from both Babel and TypeScript. Here's how:

  1. Edit your tsconfig.json to have your custom path mappings. Set anything in the root of src to be available with no preceding path reference, and allow any test file to be accessed by using tests/File.tsx:
"target": "esnext",
+ "baseUrl": ".",
+ "paths": {
+ "*": ["src/*"],
+ "tests": ["tests/*"],
+ "@components/*": ["src/components/*"],
+ },
}
  1. Configure the Babel side done by adding a new dependency, babel-plugin-module-resolver:
yarn add --dev babel-plugin-module-resolver
# or
npm install --save-dev babel-plugin-module-resolver
  1. Finally, configure your babel.config.js (note that the syntax for your babel.config.js is different from your tsconfig.json):
{
plugins: [
+ [
+ 'module-resolver',
+ {
+ root: ['./src'],
+ extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'],
+ alias: {
+ "tests": ["./tests/"],
+ "@components": "./src/components",
+ }
+ }
+ ]
]
}
Last updated on by Bartosz Kaszubowski