typescript 全面进阶指南
2023-06-06 09:49:36 0 举报
AI智能生成
typescript 全面进阶指南
作者其他创作
大纲/内容
体系
类型
目的
为 JavaScript 代码添加类型与类型检查来确保健壮性
内容及其表现
为 JavaScript 中的变量、函数等概念提供了类型的标注,
同时内置了一批类型工具,基于这些类型工具我们就能实现更复杂的类型描述,
将类型关联起来
同时内置了一批类型工具,基于这些类型工具我们就能实现更复杂的类型描述,
将类型关联起来
语法
目的
提前使用新语法或新特性来简化代码
内容及其表现
比如使用最多的可选链(?.)、空值合并(??)、装饰器等,
这些语法都已经或即将成为 ECMAScript Next 的新成员
这些语法都已经或即将成为 ECMAScript Next 的新成员
工程
目的
最终获得可用的 JavaScript 代码
内容极其表现
TypeScript 会在构建时被抹除类型代码与语法的降级。
这一能力就是通过 TypeScript Compiler(tsc)实现的。
tsc 以及 tsc 配置(TSConfig)是 TypeScript 工程层面的重要部分
这一能力就是通过 TypeScript Compiler(tsc)实现的。
tsc 以及 tsc 配置(TSConfig)是 TypeScript 工程层面的重要部分
通过类型声明的方式,在 TypeScript 中愉快地使用 JavaScript 社区的大量 npm 包
TypeScript 开发环境配置
VS Code 插件
TypeScript Importer
VS Code 内置的 TypeScript 配置
搜索 'typescript Inlay Hints',展示的配置就都是提示相关的了,推荐开启的有这么几个:
Function Like Return Types,显示推导得到的函数返回值类型;
Parameter Names,显示函数入参的名称;
Parameter Types,显示函数入参的类型;
Variable Types,显示变量的类型。
Function Like Return Types,显示推导得到的函数返回值类型;
Parameter Names,显示函数入参的名称;
Parameter Types,显示函数入参的类型;
Variable Types,显示变量的类型。
NPM 开发配置
ts-node
配置
-P,--project:指定你的 tsconfig 文件位置。默认情况下 ts-node 会查找项目下的 tsconfig.json 文件
-T, --transpileOnly:禁用掉执行过程中的类型检查过程,这能让你的文件执行速度更快,且不会被类型报错卡住。
这一选项的实质是使用了 TypeScript Compiler API 中的 transpileModule 方法
这一选项的实质是使用了 TypeScript Compiler API 中的 transpileModule 方法
--swc:在 transpileOnly 的基础上,还会使用 swc 来进行文件的编译,进一步提升执行速度
--emit:如果你不仅是想要执行,还想顺便查看下产物,可以使用这一选项来把编译产物输出到 .ts-node 文件夹下(需要同时与 --compilerHost 选项一同使用)
缺点
ts-node 本身并不支持自动地监听文件变更然后重新执行
ts-node-dev
优势
ts-node-dev 基于 node-dev(你可以理解一个类似 nodemon 的库,提供监听文件重新执行的能力) 与 ts-node 实现,
并在重启文件进程时共享同一个 TS 编译进程,避免了每次重启时需要重新实例化编译进程等操作
并在重启文件进程时共享同一个 TS 编译进程,避免了每次重启时需要重新实例化编译进程等操作
NodeJs 中的 require 逻辑
类型标注
原始类型
number
string
boolean
undefined
null
symbol
bigint
void
数组类型
使用
元组(Tuple)
同类型数组元素的类型标注
不同类型数组元素的类型标注
可选成员数组元素的类型标注
具名元组-为元组中的元素打上类似属性的标记
具名元组可选元素的修饰符
对象类型
需要特殊的类型标注来描述对象类型-interface
标记一个属性为可选-?
标记属性为只读:readonly
type/interface
interface 用来描述对象、类的结构
类型别名用来将一个函数签名、一组联合类型、一个工具类型等等抽离成一个完整独立的类型
字面量类型
概念
将实际的"值"作为类型
分类
字符串字面量类型
数字字面量类型
布尔字面量类型
对象字面量类型
场景1
总结
单独使用字面量类型比较少见,因为单个字面量类型并没有什么实际意义。
它通常和联合类型(即这里的 |)一起使用,表达一组字面量类型
它通常和联合类型(即这里的 |)一起使用,表达一组字面量类型
无论是原始类型还是对象类型的字面量类型,它们的本质都是类型而不是值。
它们在编译时同样会被擦除,
同时也是被存储在内存中的类型空间而非值空间
它们在编译时同样会被擦除,
同时也是被存储在内存中的类型空间而非值空间
联合类型
概念
一组类型的可用集合
使用
场景1
枚举
使用
规则
如果你没有声明枚举的值,它会默认使用数字枚举,并且从 0 开始,以 1 递增
如果你只为某一个成员指定了枚举值,那么之前未赋值成员仍然会使用从 0 递增的方式,之后的成员则会开始从枚举值递增
延迟求值的枚举值
延迟求值的成员不能放在最后
同时使用字符串枚举值和数字枚举值
对象与枚举的区别
枚举是双向映射的,即你可以从枚举成员映射到枚举值,也可以从枚举值映射到枚举成员
对象是单向映射的,我们只能从键映射到键值
常量枚举
函数
函数的类型签名
概念
描述了函数入参类型与函数返回值类型
使用方式1-直接在函数中进行参数和返回值的类型声明
使用方式2-使用类型别名将函数声明抽离出来
使用方式3-使用 interface 来进行函数声明
如何命名一个函数
函数声明(Function Declaration)
函数表达式(Function Expression)
void 类型
一个没有返回值(即没有调用 return 语句)的函数,其返回类型应当被标记为 void
可选参数
可选参数必须位于必选参数之后
rest参数
使用方式1
使用方式2-使用元组类型进行标注
函数重载签名(Overload Signature)
异步函数、Generator 函数的类型签名
异步函数(即标记为 async 的函数),其返回值必定为一个 Promise 类型,
而 Promise 内部包含的类型则通过泛型的形式书写,即 Promise<T>
而 Promise 内部包含的类型则通过泛型的形式书写,即 Promise<T>
Class
主要结构
构造函数
属性/方法
访问符(Accessor)
setter 方法不允许进行返回值的类型标注
修饰符
public
此类成员在类、类的实例、子类中都能被访问
private
此类成员仅能在类的内部被访问
protected
此类成员仅能在类与子类中被访问
readonly
静态成员-static
在类的内部静态成员无法通过 this 来访问,需要通过 Foo.staticHandler 这种形式进行访问
继承、实现、抽象类
基类(Base)
派生类(Derived)
内置类型
Top Type
any
概念
表示一个无拘无束的“任意类型”,它能兼容所有类型,也能够被所有类型兼容
本质
any 的本质是类型系统中的顶级类型,即 Top Type
原则
如果是类型不兼容报错导致你使用 any,考虑用类型断言替代
如果是类型太复杂导致你不想全部声明而使用 any,考虑将这一处的类型去断言为你需要的最简类型。
如你需要调用 foo.bar.baz(),就可以先将 foo 断言为一个具有 bar 方法的类型
如你需要调用 foo.bar.baz(),就可以先将 foo 断言为一个具有 bar 方法的类型
如果你是想表达一个未知类型,更合理的方式是使用 unknown
unknown
一个 unknown 类型的变量可以再次赋值,并且只能赋值给 any 与 unknown 类型的变量
any 放弃了所有的类型检查,而 unknown 并没有
对 unknown 类型进行属性访问,需要进行类型断言
对 unknown 类型进行属性访问,需要进行类型断言
Bottom Type
never
场景-一个只负责抛出错误的函数
场景2-未标明类型的数组被推导为了 never[] 类型,
这种情况仅会在你启用了 strictNullChecks 配置,
同时禁用了 noImplicitAny 配置时才会出现。
解决的办法也很简单,为这个数组声明一个具体类型即可
这种情况仅会在你启用了 strictNullChecks 配置,
同时禁用了 noImplicitAny 配置时才会出现。
解决的办法也很简单,为这个数组声明一个具体类型即可
类型断言
as
案例
双重断言
背景
如果在使用类型断言时,原类型与断言类型之间差异过大
TypeScript 会给你一个类型报错
此时它会提醒你先断言到 unknown 类型,再断言到预期类型
这是因为你的断言类型和原类型的差异太大,需要先断言到一个通用的类,即 any / unknown。
这一通用类型包含了所有可能的类型,因此断言到它和从它断言到另一个类型差异不大
TypeScript 会给你一个类型报错
此时它会提醒你先断言到 unknown 类型,再断言到预期类型
这是因为你的断言类型和原类型的差异太大,需要先断言到一个通用的类,即 any / unknown。
这一通用类型包含了所有可能的类型,因此断言到它和从它断言到另一个类型差异不大
非空断言---!
类型层级关系
最顶级的类型,any 与 unknown
特殊的 Object ,它也包含了所有的类型,但和 Top Type 比还是差了一层
String、Boolean、Number 这些装箱类型
原始类型与对象类型
字面量类型,即更精确的原始类型与对象类型嘛,需要注意的是 null 和 undefined 并不是字面量类型的子类型
最底层的 never
0 条评论
下一页