Thinking in TypeScript

2023/05/12

1. TypeScript简介

TypeScript是什么?

TypeScript是由微软开发的一门静态类型、弱类型的编程语言。它是JavaScript的超集,也就是基于JavaScript扩展的语言。

开发它的初衷

由于JS在代码编写上的灵活性,导致在运行时会带来很多不必要的类型错误。因此,TS为JavaScript添加了类型系统,它能够对代码进行静态类型检查。这样能够很大程度的减少代码在运行时的类型错误。

TypeScript和JavaScript的区别

TS完全兼容JavaScript,你能够用TS运行现有的任何JavaScript代码。TS代码编译后,会转换成原生的JavaScript代码,TS不会改变JavaScript的任何行为。它只是在编译阶段新增了类型检查,并且在编译结束后擦除这些类型。

2. 安装TypeScript

安装TS

我们可以通过NPM来安装typescript。

全局环境下安装typescript

npm install -g typescript

tsc是typescript的命令行工具,我们可以通过tsc来编译TS代码。

编写TS代码

TypeScript文件名后缀是.ts结尾

编译TS文件

使用tsc能够将TS代码编译成JS文件

运行TS代码

TS本质仍是JS,所以最后执行的仍然是JS代码。我们通过TSC编译器,将TS代码编译成JS代码后,可以通过node执行JS文件。

我们也可以通过ts-node插件来直接运行TS文件,它本质也是先将TS转换成JS,然后执行JS。

3. 类型系统

TypeScript 是一个基于 JavaScript 的静态类型检查器,能够在编译期间检查代码错误,特别是针对值类型错误的检查,能够给出错误提示。

TypeScript 在 JavaScript 基于上添加了一层 - 类型系统(这里用图表示更直观)。

3.1 静态类型检查

类型检查

TS是增加了类型系统的JS,为JS添加了静态类型检查。在编译阶段除了能够检查到代码的类型错误,还能够推断出可能的类型。支持TS的IDE,更能够在代码编写阶段进行自动类型检查和智能提示。

类型推导

根据值类型和值结构类型进行类型推导和类型匹配。对于值结构类型来说,只要结构的子集满足了目标结构类型,TS也认为它们两个类型匹配。

显示指定 Type Annotations:默认情况下,TS会隐式的自动根据上下文推导出值类型,我们也可以显示的给变量声明类型,来指定值的类型。

类型断言 Type Asserations:对于返回的值,你也可以使用 as 语法来指定具体的类型。类型断言和类型注解一样,在编译阶段会被擦除。类型断言 as 在实践中使用的也比较多,特别对于调用第三方函数或者接收回调的时候,收到到一个any入参,可以通过as来自动转换成我们自定义的类型。

类型系统

这一套的类型注解、类型检查、类型推导就是TS为JS扩展的类型系统。它能够在代码编译阶段对值类型进行自动推导和匹配,并检查类型错误。在编译完成后,又能够将类型擦除,生成原生的JS代码。通过TS的类型检查,能够很大程度上减少JS的运行时错误。

4. 基础类型

Primitive 原始类型

JavaScript支持的Primitive:string, number, bigint, boolean, undefined, symbol, null。 TypeScript的此基础上新增了void。

Array 数组

JS中的数组可以存储任意数据类型,通过new Array()来声明一个数组。在TS中,我们可以通过原始类型来定义数组,并且数组的类型是指定的。因为TS具有类型系统,所以不允许这样的事情发生,一个数组里的数据类型只能说唯一的。number[], string[] 来声明不同数据类型的数组。

any 类型

如果你不想对值进行任何的类型声明,那么可以使用any类型,any能够匹配任意类型。你如果没有对值类型进行声明,TS也无法通过上下文进行推断,那么会默认为any类型。

一个变量或者参数如果没有声明类型,TS隐式的认为是 any 类型。

但在代码里使用any类型不是一个好的规范,因为any类型跳过了类型检查,也就失去了类型检查的意义,你应该要尽可能的知道值的类型。我们可以通过设置编译选项noImplicitAny禁用any的默认推断。

Functions 函数

我们可以通过Type Annotation来指定函数入参和返回值的类型。对于匿名函数,TS会自动进行上下文类型推导。

我们可以使用“?”来声明函数入参的可选,例如,function f(x? number) {},实际上,参数x会被声明为 number undefined 的联合类型。如果不传递参数,x默认为undefined。

TS函数如果没有声明返回值,也没有返回任何值,那么函数调用默认的结果是void。但是,在JS中函数如果没有返回值,默认是unfined。这里需要注意,在TS中void和undefined不是同一个类型。

Parameter Destructuring 参数解构:对于拆解参数对象非常方便,可以参数声明一个对象类型。这样在调用函数的时候,能够自动对参数进行拆解成定义的对象。实战中常常用到的一个小技巧。

Union Type 联合类型

TS允许你通过“ ”操作符来合并多种类型,这种类型称为联合类型。也就是说,你可以给一个值声明多种类型,使用“ ”来连接不同类型。例如,function printId(id: number string) {} 函数参数id你既可以传递数字,也可以传递字符串。

通过联合类型,TS可以非常容易的进行值类型的匹配,只要满足其中任意一种类型即可。但是在使用联合类型的值时要注意,我们需要对值先做类型检查,这样TS才能推断当前你要使用的类型是哪一个。

Interface 接口

使用interface关键字可以定义一个对象类型。 、 与此相似功能的是Type Alias 类型别名,类型别名可以定义任何类型。

Interfaces和Type Alias的区别是,Interface 变量名可以重复,也就是扩展合并,而Type Alias必须唯一。

Enums 枚举类型

Enums 是TS为JS新增的特性,用于声明类型可能属于一个集合中的一种,枚举不是类型系统的一部分。

Narrow 缩小类型

将联合类型缩小为一种类型,也就是在代码中处理每一种类型。在JS中,常常使用if条件和typeof来处理每种类型的逻辑。

JS前置知识:typeof 用于获取Primitives类型,instanceOf 作用于对象类型

Object Type 对象类型

如果一个函数有多个入参,我们一般会将这些参数封装成一个对象进行传递。对象的包装我们可以直接使用对象字面量类型或者声明一个interface类型。

定义一个对象的属性,我们一般需要考虑三个元素:属性的类型,属性是否可选(属性名后面紧跟“?”),以及属性是否只读(属性名前声明 readonly)。

Index Signatures:有时候你知道接收到的值是什么类型,但是不知道值的名称,那么可以使用索引签名。例如,key/value形式的值。这在实战中,是一个编码小技巧。

5. 复杂类型

Decorators

新增特性,支持meta programming。但在TS 5.0之前个功能只是一个实验性的功能,需要显示开启才能支持(experimentalDecorators选项:true)。

Decorator本质是一个函数,通过function实现。在运行时被调用。

Decorator可以装饰在Class、Method、Property、Parameter上面。且可以装饰多个Decorators,它们的执行顺序是从上到下,返回结果是从内到外,类似递归调用。

Decorator的入参和返回值,以及执行顺序需要理清楚。

Mixin

除了通过继承类的方式来复用组件,我们还可以通过合并部位类来复用组件,这就是Mixin方式。

Modules

6. 工程配置管理

tsconfig.js

tsconfig.json 是 TS 工程的配置文件,tsc 命令就是根据 tsconfig.json 的定义,来编译工程文件输出 js 文件的。tsc 是一个编译器,能够将 ts 文件编译成 js。

CompilerOptions

–target 指定TS需要编译成的JS版本,例如,es5、es6/es2015等等。也就是说,如果你在TS中使用了es6的语法,例如,常量const和箭头函数=>等,那么TS会自动将其转换成es5语法。但是TS无法将所有es6的语法都转换成es5,比如,Promise语法。这种情况下,就需要使用另一个编译参数 –lib。

–lib 将指定的library库添加到运行时,默认继承–target参数,即target指定es6,那么lib默认使用的是es6的库。–lib更大的用处在于,你可以添加不属于当前es版本的库,例如,在es5的target中添加es6的新特性,甚至es2017、es2018、es2019的新特性。

7. 其它思考

其它类型检查语言

Flow 也是一个 JavaScript 静态类型检查工具,它不是一个新语言,它只是一个 annotation 注解。它直接作用于 JavaScript 代码,使用 Babel 编译器会对添加了注解的 JS 代码进行类型检测。

coding 感受/思维转变

有服务端/强类型语言编程经验的人,上手 TS 会非常的熟悉,因为它的写法与大多数强类型语言类似,还包括了 class、interface,等概念。

Post Directory