使用 TypeScript
TypeScript 是一种通过添加类型定义来扩展 JavaScript 的语言。新的 React Native 项目默认以 TypeScript 为目标,但也支持 JavaScript 和 Flow。
¥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.
TypeScript 入门
¥Getting Started with TypeScript
由 React Native CLI 或流行模板(如 Ignite)创建的新项目将默认使用 TypeScript。
¥New projects created by the React Native CLI or popular templates like Ignite will use TypeScript by default.
TypeScript 还可以与 Expo 一起使用,Expo 维护 TypeScript 模板,或者在将 .ts
或 .tsx
文件添加到项目时提示你自动安装和配置 TypeScript。
¥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
将 TypeScript 添加到现有项目
¥Adding TypeScript to an Existing Project
-
将 TypeScript、类型和 ESLint 插件添加到你的项目中。
¥Add TypeScript, types, and ESLint plugins to your project.
- npm
- Yarn
npm install -D @tsconfig/react-native @types/jest @types/react @types/react-test-renderer typescript
yarn add --dev @tsconfig/react-native @types/jest @types/react @types/react-test-renderer typescript
此命令添加每个依赖的最新版本。可能需要更改版本以匹配项目使用的现有包。你可以使用 React Native 升级助手 这样的工具来查看 React Native 发布的版本。
¥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.
-
添加 TypeScript 配置文件。在项目的根目录中创建
tsconfig.json
:¥Add a TypeScript config file. Create a
tsconfig.json
in the root of your project:
{
"extends": "@tsconfig/react-native/tsconfig.json"
}
-
将 JavaScript 文件重命名为
*.tsx
¥Rename a JavaScript file to be
*.tsx
你应该保留
./index.js
入口点文件,否则在打包生产构建时可能会遇到问题。¥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
对新的 TypeScript 文件进行类型检查。¥Run
tsc
to type-check your new TypeScript files.
- npm
- Yarn
npx tsc
yarn tsc
使用 JavaScript 代替 TypeScript
¥Using JavaScript Instead of TypeScript
React Native 默认新应用使用 TypeScript,但仍可以使用 JavaScript。带有 .jsx
扩展名的文件被视为 JavaScript 而不是 TypeScript,并且不会进行类型检查。JavaScript 模块仍可以由 TypeScript 模块导入,反之亦然。
¥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.
TypeScript 和 React Native 的工作原理
¥How TypeScript and React Native works
开箱即用,TypeScript 源在打包期间由 Babel 进行转换。我们建议你仅使用 TypeScript 编译器进行类型检查。这是 tsc
对于新创建的应用的默认行为。如果你将现有的 TypeScript 代码移植到 React Native,则需要使用 Babel 而不是 TypeScript。
¥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.
React Native + TypeScript 是什么样子的
¥What does React Native + TypeScript look like
你可以通过 React.Component<Props, State>
为 React 组件的 属性 和 状态 提供一个接口,这将在 JSX 中使用该组件时提供类型检查和编辑器自动补齐功能。
¥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;
你可以在 TypeScript 在线运行 中更多地探索语法。
¥You can explore the syntax more in the TypeScript playground.
哪里可以找到有用的建议
¥Where to Find Useful Advice
-
React + TypeScript 备忘单 很好地概述了如何将 React 与 TypeScript 结合使用
¥React + TypeScript Cheatsheets has a good overview on how to use React with TypeScript
将自定义路径别名与 TypeScript 结合使用
¥Using Custom Path Aliases with TypeScript
要在 TypeScript 中使用自定义路径别名,你需要将路径别名设置为同时在 Babel 和 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:
-
编辑你的
tsconfig.json
以获取 自定义路径映射。将src
根目录中的任何内容设置为可用,无需前面的路径引用,并允许使用tests/File.tsx
访问任何测试文件:¥Edit your
tsconfig.json
to have your custom path mappings. Set anything in the root ofsrc
to be available with no preceding path reference, and allow any test file to be accessed by usingtests/File.tsx
:
{
- "extends": "@tsconfig/react-native/tsconfig.json"
+ "extends": "@tsconfig/react-native/tsconfig.json",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "*": ["src/*"],
+ "tests": ["tests/*"],
+ "@components/*": ["src/components/*"],
+ },
+ }
}
-
将
babel-plugin-module-resolver
作为开发包添加到你的项目中:¥Add
babel-plugin-module-resolver
as a development package to your project:
- npm
- Yarn
npm install --save-dev babel-plugin-module-resolver
yarn add --dev babel-plugin-module-resolver
-
最后,配置
babel.config.js
(请注意,babel.config.js
的语法与tsconfig.json
不同):¥Finally, configure your
babel.config.js
(note that the syntax for yourbabel.config.js
is different from yourtsconfig.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",
+ }
+ }
+ ]
+ ]
}