跳到主要内容
新架构实战课 实操 + 基建 + 原理全维度包揽,抢先掌握 React Native 新架构精髓 立即查看 >Version: 0.71

使用 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.

使用 TypeScript 开始新项目

如果您要开始一个新项目,则有几种不同的上手方法。 您可以使用TypeScript 模板:

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

Note 如果以上命令失败,则可能是您的 PC 上全局安装了旧版本的react-nativereact-native-cli。 尝试卸载 cli 并使用npx运行 cli.

您可以使用具有两个 TypeScript 模板的Expo:

npm install -g expo-cli
expo init MyTSProject

或者,您可以使用Ignite,它也具有 TypeScript 模板:

npm install -g ignite-cli
ignite new MyTSProject

在已有的项目中添加 TypeScript

  1. 将 TypeScript 以及 React Native 和 Jest 的依赖添加到您的项目中。
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

添加一个 TypeScript 配置文件。在项目的根目录中创建一个tsconfig.json

{
"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"
]
}
  1. 创建一个jest.config.js文件来配置 Jest 以使用 TypeScript:
module.exports = {
preset: 'react-native',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node']
};
  1. 将 JavaScript 文件重命名为* .tsx:

请保留./index.js入口文件,否则将在打包生产版本时遇到问题。

  1. 运行 yarn tsc 对 TypeScript 文件进行类型检查。

TypeScript 和 React Native 是如何工作的

无需额外配置,和非 TypeScript 的 React Native 项目一样都是直接通过 Babel 体系 将您的文件转换为 JavaScript。我们建议您只使用 TypeScript 编译器的类型检查功能(而不是编译)。如果您有已经存在的 TypeScript 代码需要迁移到 React Native,这里有一些关于使用 Babel 而不是 TypeScript 编译器的注意事项

用 TypeScript 写 React Native 的示例

可以用interface来为 React 的函数组件编写Props的类型(使用React.FC<Props>)。这样在后续编码的过程中,编辑器就会根据这一类型来做类型检查并提供自动补全。

// 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.

参考资料(英文)

在 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 test/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",
+ }
+ }
+ ]
]
}