TypeScript 类型体操通关秘籍
现在,TypeScript 已经在前端圈获得了广泛的众基础。但据个人观察,很多同学还处于刚刚脱离 AnyScript 的阶段,看到 K in keyof T 这类东西就头疼,读不懂现代前端框架中普遍使用的类型操作技巧。如果你也对类型体操感到一头雾水,本文或许能为你提供一些授人以渔式的帮助。
由于本文预期的受众是完全没有高级类型操作经验的同学,因此下面我们不会直接列出一堆复杂的类型体操案例,而是从最简单的泛型变量语法等基础知识开始,逐步展示该如何从零到一地使用 TS 中强大的 type-level 编程能力。这些内容可以依次分成三个部分:
循环依赖与类型空间
类型空间与类型变量
类型变量与类型体操
如果你已经完成了 TypeScript 入门(能顺利解答 type-challenges 中的 Easy 难度问题),那么本文对你来说应该过于简单,不需要阅读。
在开始介绍具体的类型操作语法前,这里希望先铺垫个例子,借此先理清楚「TypeScript 相比于 JavaScript 到底扩展出了什么东西」,这对后面建立思维模型会很有帮助。
循环依赖与类型空间
我们都知道,JavaScript 中是不建议存在循环依赖的。假如我们为一个编辑器拆分出了 Editor 和 Element 两个 class,并把它们分别放在 editor.js 和 element.js 里,那么这两个模块不应该互相 import 对方。也就是说,下面这种形式是不提倡的:
但是在 TypeScript 中,我们很可能必须使用这样的「循环依赖」。因为往往不仅在 Editor 实例里要装着 Element 的实例,每个 Element 实例里也需要有指回 Editor 的引用。由于类型标注的存在,我们就必须这么写:
这不就造成了 JS 中忌讳的循环引用了吗?当然这么写倒也不是不能用,因为这里为了类型标注而写的 import 不会出现在编译出的 JS 代码中。
editorjs