Last updated on Oct 6, 2022

结构类型系统、标明类型系统

TypeScript 的类型属于 Structural Type System(结构类型系统:https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html#structural-type-system

Wiki - Type System(类型系统:https://en.wikipedia.org/wiki/Type_system)对此专门详细的描述了类型系统相关系统:

  1. structural type systems(结构类型系统)。例如:TypeScript
  2. nominative type systems(标明类型系统)。例如:Java、C#、Swift、Rust、C++

区别:两者对于具有相同的 Shape(形状)是否是同一类型

// nominative type systems
public class Foo {
    public string Name { get; set; }
    public int Id { get; set;}
}

public class Bar {
    public string Name { get; set; }
    public int Id { get; set; }
}

Foo foo = new Foo(); // Okay.
Bar bar = new Foo(); // Error!!!

// structural type systems
class Foo {
  method(input: string): number {
    return 1
  }
}

class Bar {
  method(input: string): number {
    return 1
  }
}

const foo: Foo = new Foo(); // Okay.
const bar: Bar = new Foo(); // Okay.

为啥 TypeScript 选择 structural type systems?

  1. 因为 JavaScript 的语言特性,动态、弱类型。

例如 Iterable,它并不要求像 C++ 语言一样要求实例必须继承于某个父类或像 Java 一样要求实例实现某个 Interface。它只检查当前对象是否实现了 @@iterator 方法。

所以 TypeScript 也顺承这一思想采用了 structural type systems 来为 JavaScript 定制一套灵活的类型系统。

另外这种类型系统可以被编程,可以说 TypeScript 的类型系统是支持类型编程的类型系统。

例如,TypeScript 中提供 keyoftypeof 等关键字就是为了提供这种功能。

type ParseQueryString<Str extends string> = 
    Str extends `${infer Param}&${infer Rest}`
        ? MergeParams<ParseParam<Param>, ParseQueryString<Rest>>
        : ParseParam<Str>;
  1. 大范围上面向对象型的语言更多地采用 nominative type systems;函数式语言偏向于 structural type systems。JavaScript 本身有多种编程范式(面向对象、函数式、原型等),不过最近几年主流方向都是函数式(JavaScript 本身arrow function、Promise 等语言特性上;React、RxJS 等前端生态发展上)