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