跳到主要内容

使用 TypeScript

TypeScript 是一种通过添加类型定义来扩展 JavaScript 的语言。新的 React Native 项目默认使用 TypeScript,同时也支持 JavaScript 和 Flow。

开始使用 TypeScript

通过 React Native CLIIgnite 等热门模板创建的新项目默认使用 TypeScript。

TypeScript 也可以与 Expo 一起使用,Expo 维护着 TypeScript 模板;或者,当项目中添加 .ts.tsx 文件时,Expo 会提示你自动安装并配置 TypeScript。

npx create-expo-app --template

将 TypeScript 添加到现有项目

  1. 将 TypeScript、类型和 ESLint 插件添加到项目中。
npm install -D typescript @react-native/typescript-config @types/jest @types/react @types/react-test-renderer
备注

此命令会添加每个依赖项的最新版本。可能需要更改版本,以匹配项目所使用的现有软件包。你可以使用 React Native Upgrade Helper 等工具,查看 React Native 所附带的版本。

  1. 添加 TypeScript 配置文件。在项目根目录中创建 tsconfig.json
tsconfig.json
{
"extends": "@react-native/typescript-config"
}
  1. 将一个 JavaScript 文件重命名为 *.tsx
注意

应保持 ./index.js 入口文件不变,否则在打包生产构建版本时可能会遇到问题。

  1. 运行 tsc,对新的 TypeScript 文件进行类型检查。
npx tsc

使用 JavaScript 代替 TypeScript

React Native 默认将新应用设置为 TypeScript,但仍然可以使用 JavaScript。扩展名为 .jsx 的文件会被视为 JavaScript 而不是 TypeScript,并且不会进行类型检查。JavaScript 模块仍然可以由 TypeScript 模块导入,反之亦然。

TypeScript 和 React Native 如何工作

开箱即用,TypeScript 源代码会在打包期间由 Babel 转换。我们建议仅使用 TypeScript 编译器进行类型检查。这是新创建应用中 tsc 的默认行为。如果你有要移植到 React Native 的现有 TypeScript 代码,那么使用 Babel 而非 TypeScript 时存在一两个注意事项

React Native + TypeScript 是什么样的

你可以通过 React.Component<Props, State> 为 React Component 的 PropsState 提供接口,这样在 JSX 中使用该组件时,就能获得类型检查和编辑器自动补全。

components/Hello.tsx
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;

你可以在 TypeScript playground 中进一步了解语法。

在哪里可以找到有用的建议

在 TypeScript 中使用自定义路径别名

要在 TypeScript 中使用自定义路径别名,需要设置路径别名,使其同时适用于 Babel 和 TypeScript。具体方法如下:

  1. 编辑 tsconfig.json,添加自定义路径映射。将 src 根目录中的所有内容设置为无需前置路径引用即可访问,并允许使用 tests/File.tsx 访问任意测试文件:
Diff
{
- "extends": "@react-native/typescript-config"
+ "extends": "@react-native/typescript-config",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "*": ["src/*"],
+ "tests": ["tests/*"],
+ "@components/*": ["src/components/*"],
+ },
+ }
}
  1. babel-plugin-module-resolver 作为开发依赖包添加到项目中:
npm install --save-dev babel-plugin-module-resolver
  1. 最后,配置 babel.config.js(注意,babel.config.js 的语法与 tsconfig.json 不同):
Diff
{
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",
+ }
+ }
+ ]
+ ]
}