| id | typescript |
|---|---|
| title | Using TypeScript |
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants';
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.
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 an 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-clioryarn global remove react-native-cli
and then run the npx command again.
Optionally, you can also use the command given below to get started with your template.
npx react-native --ignore-existing init MyApp --template react-native-template-typescript
:::
You can use Expo, which maintains TypeScript templates, or will prompt you to automatically install and configure TypeScript when a .ts or .tsx file is added to your project:
npx create-expo-app --templateyarn create expo-app --templateOr you could use Ignite, which also has a TypeScript template:
npm install -g ignite-cli
ignite new MyTSProjectyarn global add ignite-cli
ignite new MyTSProject- Add TypeScript and the types for React Native and Jest to your project.
npm install -D typescript @types/jest @types/react @types/react-native @types/react-test-rendereryarn add -D typescript @types/jest @types/react @types/react-native @types/react-test-renderer- Add a TypeScript config file. Create a
tsconfig.jsonin the root of your project:
{
"compilerOptions": {
"allowJs": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"isolatedModules": true,
"jsx": "react-native",
"lib": ["es2017"],
"types": ["react-native", "jest"],
"moduleResolution": "node",
"noEmit": true,
"strict": true,
"target": "esnext"
},
"exclude": [
"node_modules",
"babel.config.js",
"metro.config.js",
"jest.config.js"
]
}- Create a
jest.config.jsfile to configure Jest to use TypeScript
module.exports = {
preset: 'react-native',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node']
};- Rename a JavaScript file to be
*.tsx
You should leave the
./index.jsentrypoint file as it is otherwise you may run into an issue when it comes to bundling a production build.
- Run
yarn tscto type-check your new TypeScript files.
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.
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.
import React from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
export type Props = {
name: string;
baseEnthusiasmLevel?: number;
};
const Hello: React.FC<Props> = ({
name,
baseEnthusiasmLevel = 0
}) => {
const [enthusiasmLevel, setEnthusiasmLevel] = React.useState(
baseEnthusiasmLevel
);
const onIncrement = () =>
setEnthusiasmLevel(enthusiasmLevel + 1);
const onDecrement = () =>
setEnthusiasmLevel(
enthusiasmLevel > 0 ? enthusiasmLevel - 1 : 0
);
const getExclamationMarks = (numChars: number) =>
numChars > 0 ? Array(numChars + 1).join('!') : '';
return (
<View style={styles.container}>
<Text style={styles.greeting}>
Hello {name}
{getExclamationMarks(enthusiasmLevel)}
</Text>
<View>
<Button
title="Increase enthusiasm"
accessibilityLabel="increment"
onPress={onIncrement}
color="blue"
/>
<Button
title="Decrease enthusiasm"
accessibilityLabel="decrement"
onPress={onDecrement}
color="red"
/>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
greeting: {
fontSize: 20,
fontWeight: 'bold',
margin: 16
}
});
export default Hello;You can explore the syntax more in the TypeScript playground.
- TypeScript Handbook
- React's documentation on TypeScript
- React + TypeScript Cheatsheets has a good overview on how to use React 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:
- Edit your
tsconfig.jsonto have your custom path mappings. Set anything in the root ofsrcto be available with no preceding path reference, and allow any test file to be accessed by usingtests/File.tsx:
"target": "esnext",
+ "baseUrl": ".",
+ "paths": {
+ "*": ["src/*"],
+ "tests": ["tests/*"],
+ "@components/*": ["src/components/*"],
+ },
}- Add
babel-plugin-module-resolveras a development package to your project:
npm install --save-dev babel-plugin-module-resolveryarn add --dev babel-plugin-module-resolver- Finally, configure your
babel.config.js(note that the syntax for yourbabel.config.jsis different from yourtsconfig.json):
{
plugins: [
+ [
+ 'module-resolver',
+ {
+ root: ['./src'],
+ extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'],
+ alias: {
+ tests: ['./tests/'],
+ "@components": "./src/components",
+ }
+ }
+ ]
]
}