# TypeScript 在 React 中的使用

# 1. 使用 CRA 创建支持 TS 的项目

# 1.1. 创建项目

说明:

  • React 脚手架工具 create-react-app(简称 CRA) 默认支持 TypeScript

示例:

# "react-ts-basic" 为项目名称
npx create-react-app react-ts-basic --template typescript

# We suggest that you begin by typing:
# 
#   cd react-ts-basic
#   npm start

参考:

# 1.2. 目录结构

与 JS 项目对比,发现:

  1. 新增 tsconfig.json 文件
  2. 组件的文件扩展名变为 .tsx
  3. 新增 react-app-env.d.ts 文件 (React 项目默认的类型声明文件)

# 1.3. react-app-env.d.ts

tsconfig.json 中的 include 配置:

自动导入 .d.ts 文件的示例:

/* common.d.ts */
type MyCommonType = number;


/* common.d.ts */
let a: MyCommonType = 1;

export default {};

同样 src/react-app-env.d.ts 文件也会自动加载,其内容为:

/// <reference types="react-scripts" />

/// <reference types="react-scripts" /> 为三斜线指令:

  • 类似于 import,表示依赖哪个(包的)类型声明文件
  • 告诉 TS 加载 react-scripts 这个包提供的类型声明文件

react-scripts 的类型声明文件包含:

  1. react、react-dom、node 的类型
  2. 图片、样式等模块的类型(允许在 TS 代码中 import 图片、样式等)

# 2. tsconfig.json 配置文件

说明:

顶层属性:

include
compilerOptions

files
extends
exclude
references

# 2.1. include

说明:

  • Specifies an array of filenames or patterns to include in the program.
  • These filenames are resolved relative to the directory containing the tsconfig.json file.

示例:

{
  "include": ["src/**/*", "tests/**/*"]
}

# 2.2. compilerOptions

# 2.2.1. target

说明:

  • 编译后的 JS 代码的版本

可选值:

es3         (default)
es5
es6/es2015
es2016
es2017
es2018
es2019
es2020
es2021
es2022
esnext

参考:https://www.typescriptlang.org/tsconfig#target (opens new window)

# 2.2.2. lib

说明:

  • 包含哪些库的类型声明
  • 相当于指定代码运行的环境

示例:

{
  "compilerOptions": {
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ]
  }
}

参考:https://www.typescriptlang.org/tsconfig#lib (opens new window)

# 2.2.3. allowJs

说明:

  • 允许在 ts 代码中导入 js 文件
  • 推荐开启

参考:https://www.typescriptlang.org/tsconfig#allowJs (opens new window)

# 2.2.4. skipLibCheck

说明:

  • 跳过声明文件的类型检查
  • 常用于,当 node_modules 有多份同一个库的类型时
  • 推荐开启

参考:https://www.typescriptlang.org/tsconfig#skipLibCheck (opens new window)

# 2.2.5. esModuleInterop

说明:

  • 屏蔽 ESModule、CommonJS 之间的差异
  • 建议开启,通常也会开启 compilerOptions.allowSyntheticDefaultImports

示例:

/*
  关闭
 */
const fs = require('fs');
fs.readFileSync("file.txt", "utf8");

const lodash = require('loadash');
lodash.default.chunk(/* ... */); // 需要加上 default


/*
  开启
 */
import * as fs from "fs";
import lodash from "lodash";

fs.readFileSync("file.txt", "utf8");
lodash.chunk(["a", "b", "c", "d"], 2);

参考:https://www.typescriptlang.org/tsconfig#esModuleInterop (opens new window)

# 2.2.6. allowSyntheticDefaultImports

说明:

  • 简化默认导入的代码
  • 建议开启

示例:

/*
  关闭
 */
import * as fs from "fs";

fs.readFileSync("file.txt", "utf8");


/*
  开启,
    如果没有默认导出,babel 会自动创建
    
      module.exports = allFunctions;
      module.exports.default = allFunctions; // 自动创建的
 */
import fs from "fs";

fs.readFileSync("file.txt", "utf8");

# 2.2.7. strict

说明:

  • 开启一系列的严格选项
  • 建议开启

参考:https://www.typescriptlang.org/tsconfig#strict (opens new window)

# 2.2.8. forceConsistentCasingInFileNames

说明:

  • 区分文件名大小写
  • 默认开启。建议开启

参考:https://www.typescriptlang.org/tsconfig#forceConsistentCasingInFileNames (opens new window)

# 2.2.9. noFallthroughCasesInSwitch

说明:

  • switch 语句不能有空 case
  • 也就是不能匹配多个 case
  • 建议开启。

示例:

const a: number = 6;
 
switch (a) {
  case 0: // 这个 case 里没有 break、return、throw
    console.log("even"); 
  case 1:
    console.log("odd");
    break;
}

参考:https://www.typescriptlang.org/tsconfig#noFallthroughCasesInSwitch (opens new window)

# 2.2.10. module

说明:

  • 生成的 JS 代码的模块化方案

可选值:

none
commonjs            (default, if target is ES3 or ES5)
amd
umd
system
es6/es2015          (default, if target is not ES3 or ES5)
es2020
es2022
esnext
node16
nodenext

参考:https://www.typescriptlang.org/tsconfig#module (opens new window)

# 2.2.11. moduleResolution

说明:

  • 模块解析(查找)策略

参考:https://www.typescriptlang.org/tsconfig#moduleResolution (opens new window)

# 2.2.12. resolveJsonModule

说明:

  • 解析 json 模块
  • 开启后,允许导入 .json 后缀的文件

参考:https://www.typescriptlang.org/tsconfig#resolveJsonModule (opens new window)

# 2.2.13. isolatedModules

说明:

  • 独立的模块
  • 开启后,非模块化(没有导入导出关键字)的文件会报错

参考:https://www.typescriptlang.org/tsconfig#isolatedModules (opens new window)

# 2.2.14. noEmit

说明:

  • 只进行类型检查,不生成任何文件
  • 将编译工作交给 babel 来做

参考:https://www.typescriptlang.org/tsconfig#noEmit (opens new window)

# 2.2.15. jsx

说明:

  • 指定将 jsx 编译成什么样的 js

参考:https://www.typescriptlang.org/tsconfig#jsx (opens new window)

# 3. 命令行指定配置

说明:

# 执行 tsc 命令,启用 tsconfig.json,并编译整个项目
tsc

# 编译单个文件,且指定编译配置
tsc hello.ts --target es6

# 4. react 中的常用类型

react 开发主要任务就是写组件,有两种组件:

  1. 函数组件
  2. class 组件

# 4.1. 函数组件

包括:

  • 组件的类型
  • 组件的属性
  • 组件属性的默认值
  • 事件绑定、事件对象
本章目录