02-React添加TS
JS 本身是一门动态类型语言,有了对静态类型的需求。TS 诞生
1. React + TS
# 直接创建
npx create-react-app my-app --template typescript
项目改变:
.js
=>.tsx
- 增加了
tsconfig.json
文件
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": [
"src"
]
}
1. tsconfig.json
tsconfig.json
是 TS 的配置文件,TS 是开发环境中的语言,浏览器不认识 TS
- 在生产阶段早期是通过webpack 插件
ts-loader
将 TS 编译成 JS ts-loader
在内部是调用了 TS 的官方编译器tsc
。所以ts-loader
和tsc
共享tsconfig.json
- 存在问题:
ts-loader
将 TS 编译成 JS,为了兼容低版本的浏览器,一般还会通过 babel 转化成 es5 低版本的 JS。 所以这个过程是这样的 TS > TS 编译器 > JS > Babel > JS (es5) - Babel 7 之前是不支持 TS 的,所以整个的解析链路很长。在 Babel7 中做了一个改变,使用
babel-loader
就能直接解析 TS, react 脚手架中使用的也是babel-loader
,配置文件不变依然是tsconfig.json
Babel 是一个 JS 编译器
主要用于将采用 ECMAScript 2015+(es6+)语法编写的代码转换为向后兼容的 JS 语法,以便能够运行在当前和旧版本的浏览器或其他环境中
配置文档
编译器启动时,首先会读取 tsconfig.json,以获取有关如何编译项目的说明(例如,要编译哪些源文件,在哪里存储输出等)。 现在,我们来研究一下上图出现的比较常见的编译器 tsconfig 选项。
"target": "es5"
这个属性定义了你编译后的目标javascript版本一般来说,我们需要让他编译为es5,这样就可以被主流浏览器解读了。当然,你说我的react代码不是给浏览器看的,比如说,你使用的是react-native 开发手机app,那么这里的选项可以选择es6。除了e s5和es6,我们还有很多其他常见的选项。ES5,ES6/ES2015,ES2016,ES2017,ES2018,ES2019,ES2020,ESNext,等等等等。
"lib": [
"dom",
"dom.iterable",
"esnext"
]
这个属性列出了编译期间需要被包括进来的库文件。通过这些库文件,告诉typescript编译器可以使用哪些功能。比如说,我们这里有一个dom的库文件这个文件会告诉编译器DOM API的接口,所以当我们在ts代码中使用 DOM 的时候,比如说执行"document. getElementById("root")"这句话的时候,编译器就会知道该如何进行检查。如果我们不设置这个选项,那么编译器也有自己默认的库文件列表。
"allowJs": true
允许混合编译JavaScript文件。(允许编译器编译JS,JSX文件)
"skipLibCheck": true
忽略所有的声明文件( *.d.ts
)的类型检查。
"esModuleInterop": true
这个选项允许我们使用commonjs的方式import默认文件。
"allowSyntheticDefaultImports": true
允许从没有设置默认导出的模块中默认导入。这并不影响代码的输出,仅为了类型检查。
"strict": true
启用所有严格类型检查选项。
"forceConsistentCasingInFileNames": true
禁止对同一个文件的不一致的引用。
"noFallthroughCasesInSwitch": true
不允许switch的case语句贯穿。
switch语句,除非明确地中断流程,否则每次条件判断后都贯穿到下一个case条件。
"module": "esnext"
这里配置的是我们代码的模块系统,比较常见的有Node.js的CommonJS系统,ES6标准的esnext系统以及requirejs的AMD系统。我们这里使用的是ES6标准的esnext系统,不过如果把这里换成CommonJs也是可以的。
"moduleResolution": "node"
这个选项决定了我们编译器的工作方式,也决定了我们各个文件之间调用、import的工作流程。这里曾经有两个选项,"node" and "classic",但是"c lassic"这个选项在2019年12月就已经废弃了。
"resolveJsonModule": true
译选项可允许从 .json
中导入、导出其类型。(详情看示例1:)
"isolatedModules": true
将每个文件作为单独的模块
"noEmit": true
开启这个选项表示当发生错误的时候,编译器不会生成 JavaScript 代码。
"jsx": "react-jsx"
允许编译器支持编译 react-jsx 代码。
示例1:
settings.json
{
"repo": "TypeScript",
"dry": false,
"debug": false
}
index.ts
import settings from "./settings.json";
settings.debug === true; // OK
settings.dry === 2; // Error: '===' 不能用于比较 boolean 和 number 类型
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"resolveJsonModule": true,
"esModuleInterop": true
}
}
参考: 编译器选项 https://www.tslang.cn/docs/handbook/compiler-options.html