TypeScript
TypeScript
简介
如何理解 Interface 和 Type 的异同
类型(Type)不可以合并,但接口(Interface)可以合并。可以理解为某个函数可以实现多个接口,但是作为变量,它只有一种类型。
裸类型是什么?
TODO,裸类型在带入运算时会自动展开,非裸类型则不会。
type WrapNaked<T> = T extends any ? { o: T } : never
type WrapUnNaked<T> = { o: T } extends any ? { o: T } : never
type Foo = WrapNaked<string | number | boolean>
// { o: string } | { o: number } | { o: boolean }
type Bar = WrapUnNaked<string | number | boolean>
// { o: string | number | boolean }
高级类型
Iterable 和 Array 是什么关系?
实现了 Symbol.iterator 接口的对象都视为是 Iterable 的对象,所以 Array、Map、Set、String、Int32Array 等都是 Iterable 的。
应用
怎么给 Window 新增属性?
同名接口会自动合并,所以写一个新的 Window 对象的接口就好了。
declare interface Window {
propertyA: string;
}
Links
TODO,In typescript, why is [boolean, string?]
different from [boolean, string] | [boolean]
?
类型体操
什么是类型体操?
TypeScript 的类型系统是图灵完备的,这意味着能用 JavaScript 解决的问题,用 TypeScript 的类型系统同样能解决,只是实现方式不一样。尽管完成某种“实现”的方式可能非常复杂,但人们就像玩玩具一样喜欢玩它,或是把它看作某种脑力运动。充满技巧,有乐趣,复杂,又花里胡哨,所以是体操咯。
什么是图灵完备?
图灵完备通常指一门编程语言,这意味着这门语言能完成所有图灵机能做的工作。图灵机简单来说,是一个带有无限长度纸带的机器,纸带上有规律组成的 0 和 1,而图灵机通过读写纸带,就可以模拟任何可以实现的计算。
见:什么是图灵完备 @bili,TODO,什么是图灵完备 @zhihu
Memo
经验
大规模采用 TypeScript 之后的 10 个见解
尽管 TypeScript Design Goals 明确表示了避免在未来引入更多的运行时特征,但在发展过程中,TS 扩展了一小部分不太适合 TS = JS + Types 这个模型的功能,enum, namespace, parameter properties 以及 experimental decorators 都需要有将他们扩展为运行时代码的语义,而 JavaScript 引擎很可能永远都不会为这些功能提供支持。
彭博社有专门的工具阻止使用这些不良设计,他们希望自己的代码一直和 ES 标准保持统一。
编译器更新其实值得,带来的兼容性只有两点:一是新的类型检查会暴露过去没有发现的错误,二是在同一个生态系统中如果各个项目使用不同版本的编译器,可能产物不通用。
保持一致的 tsconfig 设置是非常重要的,但最终我们放弃了严格模式,选择牺牲灵活性来保持所有项目配置的一致性。
当设计以 tsconfig.a.json 配置编译的代码被配置了 tsconfig.b.json 的工具引用后就可能出问题。
Ambient Modules 特别之处在于,TypeScript 在发表声明时保持对修饰符的引用,从而避免将它们转化为相对路径。
我们的平台会确保在运行时中每个包只有一个版本的存在。我们希望对类型提供一种 “精确且唯一” 的定义,更好的反应运行时环境。
不可能实现。
TypeScript 仍无法知晓它生成的文件中是否存在不安全的导入
因为从某个库的私有包中引入类型是不安全的,这种引入不受库接口的兼容性限制。
有时 TypeScript 会将依赖中的类型内联传递给当前的类型。我们见过一些极端的例子,由于这些重复的类型定义,声明文件的大小从 7KB 膨胀到了 700KB。
如何防止类型内联:
- 使用 interface 代替 type。
- 对输出添加类型注释,显式类型注释可以强制指定引用的行为,防止内联
Type Shaking 有时会效果极为显著。我们曾经遇到过一些包中超过 90% 文件中有超过 90% 的类型定义行是可以去掉的。
反对
“TypeScript 不值得!”前端框架 Svelte 作者宣布重构代码,反向迁移到 JavaScript 引争议
2023 年 5 月 9 日,Svelte 团队发布 TS to JSDoc Conversion 的 PR,讨论点在 JSDoc 对类型开发的友好程度不如 TS。作者 Rich Harris 表示原因比较复杂。
团队在 Sveltekit 中尝试这么做并取得了良好效果,所以想在 Svelte 4.0 也这么做。
“这就没必要了,因为在构建应用程序的过程中,大家无论如何都需要构建的步骤。应用开发的重点在于优化代码、控制它的体量,并把一切都捆绑起来。但如果是想构建一个库,那我强烈建议改用 JSDoc。”
如果是构建应用程序,没必要转向 JSDoc。
对 Svelte 而言,框架本身没有放弃类型安全;对开发者而言,能降低贡献门槛;对用户而言,代码直接指向源码方便调试,也助于能减小代码体积。
项目设置
isolatedModules
许多编译工具如 Babel 不支持在“一个系统层面”角度理解类型。所以需要开启 isolatedModules。开启后,TS 会将每一个 TS 文件都视为独立的 Module,这需要项目使用 ES Module 语法,但同时,TS 会带来更严格的类型检测支持。
在 vite-based 项目中,这个选项应该且默认打开。