TypeScript基础概念
在 JavaScript 中,对象(Object)是最常用的类型之一,我们会使用大量的对象字面量来组织数据,我们经常将很多不同的参数塞进一个对象,或者从一个函数中返回一个对象,对象中还可以再嵌套对象。可以说对象是 JavaScript 中最常用的数据容器,但并没有类型去约束它。
例如 request 这个库会要求使用者将发起请求的所有参数一股脑地以一个对象的形式作为参数传入。这就是非常典型的 JavaScript 风格。再比如 JavaScript 中一个 Promise 对象只需有 then 和 catch 这两个实例方法就可以,而并不真的需要真的来自标准库中的 Promise 构造器,实际上也有很多第三方的 Promise 的实现,或一些返回类 Promise 对象的库(例如一些 ORM)。
在 JavaScript 中我们通常只关注一个对象是否有我们需要的属性和方法,这种范式被称为「鸭子类型(Duck typing)」,就是说「当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子」。
所以 TypeScript 选择了一种基于属性的类型系统(Structural type system),这种类型系统不再关注一个变量被标称的类型(由哪一个构造器构造),而是 在进行类型检查时,将对象拆开,抽丝剥茧,逐个去比较组成这个对象的每一个不可细分的成员。如果一个对象有着一个类型所要求的所有属性或方法,那么就可以当作这个类型来使用。
这就是 TypeScript 类型系统的核心 —— Interface(接口):
interface LabeledValue {
label: string
}
TypeScript 并不关心 Interface 本身的名字,与其说是「类型」,它更像是一种约束。一个对象只要有一个字符串类型的 label 属性,就可以说它满足了 LabeledValue 的约束。它可以是一个其他类的实例、可以是字面量、可以有额外的属性;只要它满足 LabeledValue 所要求的属性,就可以被赋值给这个类型的变量、传递给这个类型的参数。
前面提到 Interface 实际上是一组属性或一组约束的集合,说到集合,当然就可以进行交集、并集之类的运算。例如 type C = A & B 表示 C 需要同时满足类型 A 和类型 B 的约束,可以简单地实现类型的组合;而 type C = A | B 则表示 C 只需满足 A 和 B 任一类型的约束,可以实现联合类型(Union Type)。
如果想要简单调试ts的特性,可以在这里TypeScript练习
在线调试。