如果x要兼容y,那么y至少具有与x相同的属性(只有检查对象)
比较原始类型和对象类型
1 2 3 4 5 6 7 8 9 10 11 12 13
| interface Named { name: string; }
let x: Named;
let y = { name: 'Alice', location: 'Seattle' }; x = y;
function greet(n: Named) { console.log('Hello, ' + n.name); } greet(y);
|
比较两个函数
1 2 3 4 5 6 7 8 9
| let x = (a: number) => 0; let y = (b: number, s: string) => 0; y = x
比较返回值类型: 目标函数返回值类型的子类型 let x = () => ({name: 'Alice'}); let y = () => ({name: 'Alice', location: 'Seattle'});
x = y;
|
- 函数参数双向协变: 只有当源函数参数能够赋值给目标函数或者反过来时才能赋值成功。
- 可选参数及剩余参数: 可选和必须参数是可互换,剩余参数被当作无限个可选参数
- 函数重载: 源函数的每个重载都要在目标函数上找到对应的函数签名
枚举
类
- 比较两个类类型的对象时,只有实例(方法)的成员会被比较(静态和构造不比较)
- 类的私有成员和受保护成员:
- 目标类型包含一个私有/保护成员,那么源类型必须包含来自同一个类的这个私有/保护成员.
- 这允许子类赋值给父类,但是不能赋值给其它有同样类型的类。
泛型: 没参时,当作any比较;有参时,比较参数类型
1 2 3 4 5 6
| interface NotEmpty<T> { data: T } let x: NotEmpty<number>; let y: NotEmpty<string>; x = y
|
高级主题: 子类型与赋值
- 赋值扩展了子类型兼容性,允许和any来回赋值,以及enum和对应数字值之间的来回赋值
- 类型兼容性是由赋值兼容性来控制的,即使在implements和extends语句也不例外