跳至主内容

在 React Native 中使用 TypeScript

· 1 分钟阅读
Ash Furrow
Artsy 软件工程师
非官方测试版翻译

本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →

JavaScript!我们都爱它。但有些人也钟爱类型系统。幸运的是,有多种方案可以为 JavaScript 增加强类型支持。我最喜欢的是 TypeScript,不过 React Native 默认支持 Flow。选择哪种方案完全取决于个人偏好,它们各自有不同的方式为 JavaScript 添加类型的魔力。今天,我们将探讨如何在 React Native 应用中使用 TypeScript。

本文参考了微软的 TypeScript-React-Native-Starter 仓库指南。

更新:自本文撰写以来,配置过程变得更加简单。只需运行以下单个命令,即可替代本文描述的所有设置:

npx react-native init MyAwesomeProject --template react-native-template-typescript

不过 Babel 的 TypeScript 支持确实_存在_一些限制,上文提到的博文对此有详细说明。本文概述的步骤仍然有效,Artsy 在生产环境中仍在使用 react-native-typescript-transformer。但要在 React Native 和 TypeScript 中快速上手,使用上述命令是最便捷的方式。如有需要,之后可以随时切换。

无论如何,祝您使用愉快!原始博文继续如下。

准备工作

由于您可能在不同平台上开发,面向多种设备类型,基础设置可能较为复杂。您应首先确保能在不使用 TypeScript 的情况下运行普通的 React Native 应用。请按照 React Native 官网的说明开始操作。当您成功部署到设备或模拟器后,就可以开始创建 TypeScript React Native 应用了。

您还需要安装 Node.jsnpmYarn

初始化

当您尝试搭建好普通 React Native 项目后,就可以开始添加 TypeScript 了。让我们立即开始吧。

react-native init MyAwesomeProject
cd MyAwesomeProject

添加 TypeScript

下一步是将 TypeScript 添加到项目中。以下命令将:

  • 向项目添加 TypeScript

  • 添加 React Native TypeScript Transformer 到项目

  • 初始化空的 TypeScript 配置文件(我们稍后将配置)

  • 添加空的 React Native TypeScript Transformer 配置文件(我们稍后将配置)

  • 添加 React 和 React Native 的类型定义

好的,让我们运行这些命令:

yarn add --dev typescript
yarn add --dev react-native-typescript-transformer
yarn tsc --init --pretty --jsx react
touch rn-cli.config.js
yarn add --dev @types/react @types/react-native

tsconfig.json 文件包含 TypeScript 编译器的所有设置。上述命令创建的默认配置基本可用,但请打开文件并取消注释以下行:

{
/* Search the config file for the following line and uncomment it. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
}

rn-cli.config.js 包含 React Native TypeScript Transformer 的设置。打开该文件并添加以下内容:

module.exports = {
getTransformModulePath() {
return require.resolve('react-native-typescript-transformer');
},
getSourceExts() {
return ['ts', 'tsx'];
},
};

迁移至 TypeScript

将生成的 App.js__tests_/App.js 文件重命名为 App.tsxindex.js 需要保留 .js 扩展名。所有新文件应使用 .tsx 扩展名(如果文件不包含 JSX,则使用 .ts)。

如果此时尝试运行应用,可能会遇到类似 object prototype may only be an object or null 的错误。这是因为在同一行同时导入 React 的默认导出和命名导出时出现了问题。请打开 App.tsx 文件并修改顶部导入语句:

-import React, { Component } from 'react';
+import React from 'react'
+import { Component } from 'react';

部分问题源于 Babel 和 TypeScript 处理 CommonJS 模块的方式差异。未来两者将统一为相同的行为模式。

至此,您应该能够正常运行 React Native 应用了。

添加 TypeScript 测试环境

React Native 默认集成 Jest,要在 TypeScript 环境下测试 React Native 应用,我们需要安装 ts-jestdevDependencies

yarn add --dev ts-jest

接着打开 package.json 文件,将 jest 字段替换为以下配置:

{
"jest": {
"preset": "react-native",
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"transform": {
"^.+\\.(js)$": "<rootDir>/node_modules/babel-jest",
"\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
"testPathIgnorePatterns": [
"\\.snap$",
"<rootDir>/node_modules/"
],
"cacheDirectory": ".jest/cache"
}
}

这将配置 Jest 使用 ts-jest 处理 .ts.tsx 文件。

安装依赖类型声明

为了获得最佳的 TypeScript 开发体验,我们需要让类型检查器理解依赖项的结构和 API。部分库会在发布包中包含 .d.ts 文件(类型声明/类型定义文件),这些文件能描述底层 JavaScript 的结构。对于其他库,我们需要显式安装 @types/ npm 作用域下的对应类型包。

例如,这里我们需要为 Jest、React、React Native 和 React Test Renderer 安装类型声明:

yarn add --dev @types/jest @types/react @types/react-native @types/react-test-renderer

我们将这些类型声明包保存为开发依赖,因为这是一个 React Native 应用,仅在开发阶段使用这些依赖而非运行时。如果是要发布到 NPM 的库,可能需要将部分类型依赖添加为常规依赖。

您可在此处深入了解如何获取 .d.ts 文件

忽略更多文件

在版本控制中,建议忽略 .jest 文件夹。如果使用 git,直接在 .gitignore 文件中添加条目即可:

# Jest
#
.jest/

建议此时将文件提交到版本控制系统作为检查点。

git init
git add .gitignore # import to do this first, to ignore our files
git add .
git commit -am "Initial commit."

添加组件

现在让我们为应用添加组件。创建 Hello.tsx 组件文件——虽然这是个教学示例组件而非实际应用代码,但能展示如何在 React Native 中使用 TypeScript 编写非简单组件。

创建 components 目录并添加以下示例:

// components/Hello.tsx
import React from 'react';
import {Button, StyleSheet, Text, View} from 'react-native';

export interface Props {
name: string;
enthusiasmLevel?: number;
}

interface State {
enthusiasmLevel: number;
}

export class Hello extends React.Component<Props, State> {
constructor(props: Props) {
super(props);

if ((props.enthusiasmLevel || 0) <= 0) {
throw new Error(
'You could be a little more enthusiastic. :D',
);
}

this.state = {
enthusiasmLevel: props.enthusiasmLevel || 1,
};
}

onIncrement = () =>
this.setState({
enthusiasmLevel: this.state.enthusiasmLevel + 1,
});
onDecrement = () =>
this.setState({
enthusiasmLevel: this.state.enthusiasmLevel - 1,
});
getExclamationMarks = (numChars: number) =>
Array(numChars + 1).join('!');

render() {
return (
<View style={styles.root}>
<Text style={styles.greeting}>
Hello{' '}
{this.props.name +
this.getExclamationMarks(this.state.enthusiasmLevel)}
</Text>

<View style={styles.buttons}>
<View style={styles.button}>
<Button
title="-"
onPress={this.onDecrement}
accessibilityLabel="decrement"
color="red"
/>
</View>

<View style={styles.button}>
<Button
title="+"
onPress={this.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',
},
});

哇!内容有点多,我们来分解说明:

  • 我们不再渲染 divspanh1 等 HTML 元素,而是渲染 ViewButton 等组件。这些是跨平台工作的原生组件。

  • 样式使用 React Native 提供的 StyleSheet.create 函数定义。React 的样式表允许我们通过 Flexbox 控制布局,并使用类似 CSS 的语法进行样式设计。

添加组件测试

组件创建完成后,让我们为其编写测试。

我们已安装 Jest 作为测试运行器。接下来将为组件编写快照测试,需要安装快照测试所需的附加组件:

yarn add --dev react-addons-test-utils

现在在 components 目录下创建 __tests__ 文件夹,并为 Hello.tsx 添加测试:

// components/__tests__/Hello.tsx
import React from 'react';
import renderer from 'react-test-renderer';

import {Hello} from '../Hello';

it('renders correctly with defaults', () => {
const button = renderer
.create(<Hello name="World" enthusiasmLevel={1} />)
.toJSON();
expect(button).toMatchSnapshot();
});

首次运行测试时,它会创建渲染组件的快照并存储在 components/__tests__/__snapshots__/Hello.tsx.snap 文件中。当您修改组件后,需要更新快照并检查是否有意外变更。您可以在这里了解更多关于测试 React Native 组件的内容。

后续计划

请查看官方 React 教程和状态管理库 Redux。这些资源在开发 React Native 应用时非常有用。此外,您还可以了解 ReactXP,这是一个完全用 TypeScript 编写的组件库,同时支持 Web 端 React 和 React Native。

祝您在类型更安全的 React Native 开发环境中玩得开心!