website/versioned_docs/version-0.82/typescript.md
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. New React Native projects target TypeScript by default, but also support JavaScript and Flow.
New projects created by the React Native CLI or popular templates like Ignite will use TypeScript by default.
TypeScript may also be used with 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 --template
npm install -D typescript @react-native/typescript-config @types/jest @types/react @types/react-test-renderer
yarn add --dev typescript @react-native/typescript-config @types/jest @types/react @types/react-test-renderer
:::note This command adds the latest version of every dependency. The versions may need to be changed to match the existing packages used by your project. You can use a tool like React Native Upgrade Helper to see the versions shipped by React Native. :::
tsconfig.json in the root of your project:{
"extends": "@react-native/typescript-config"
}
*.tsx:::warning
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.
:::
tsc to type-check your new TypeScript files.npx tsc
yarn tsc
React Native defaults new applications to TypeScript, but JavaScript may still be used. Files with a .jsx extension are treated as JavaScript instead of TypeScript, and will not be typechecked. JavaScript modules may still be imported by TypeScript modules, along with the reverse.
Out of the box, TypeScript sources are transformed by Babel during bundling. We recommend that you use the TypeScript compiler only for type checking. This is the default behavior of tsc for newly created applications. 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 {useState} from 'react';
import {Button, StyleSheet, Text, View} from 'react-native';
export type Props = {
name: string;
baseEnthusiasmLevel?: number;
};
function Hello({name, baseEnthusiasmLevel = 0}: Props) {
const [enthusiasmLevel, setEnthusiasmLevel] = 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.
To use custom path aliases with TypeScript, you need to set the path aliases to work from both Babel and TypeScript. Here's how:
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:{
- "extends": "@react-native/typescript-config"
+ "extends": "@react-native/typescript-config",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "*": ["src/*"],
+ "tests": ["tests/*"],
+ "@components/*": ["src/components/*"],
+ },
+ }
}
babel-plugin-module-resolver as a development package to your project:npm install --save-dev babel-plugin-module-resolver
yarn add --dev babel-plugin-module-resolver
babel.config.js (note that the syntax for your babel.config.js is different from your tsconfig.json):{
presets: ['module:metro-react-native-babel-preset'],
+ plugins: [
+ [
+ 'module-resolver',
+ {
+ root: ['./src'],
+ extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'],
+ alias: {
+ tests: ['./tests/'],
+ "@components": "./src/components",
+ }
+ }
+ ]
+ ]
}