structural subtyping.
如果 x 中的成员在 y 中都有,那么 y 可以赋值给 x。但是注意这里不能直接赋值,需要间接赋值
interface Named {
name: string;
}
let x: Named = { name: "Alice", location: "Seattle" }; // ERROR:Named 中没有 location 类型
// y's inferred type is { name: string; location: string; }
let y = { name: "Alice", location: "Seattle" }; // OK。间接赋值,y 有包含 Named 中的 name
x = y;
function greet(n: Named) {
console.log("Hello, " + n.name);
}
greet(y); // OK
Comparing two functions
这里来看一下,不同的 function 之间是如何兼容的。
- 参数:如果 A 函数的所有的参数,在函数类型 B 的所有的参数中都能找到(这里忽略参数名,值对比参数位置和对应位置的类型),并且类型匹配,那么说 A 函数在赋值给函数类型 B 时,参数类型校验能够通过
let x = (a: number) => 0;
type y = (b: number, s: string) => number;
let Y:y = x // OK
// 例如,Array 的方法, item 可以只穿一个参数
items.forEach((item) => console.log(item));
- 返回值:两个函数的返回值的兼容,依靠前面的 structural subtyping
type student = {
age: number,
name: string
}
interface func {
(): student
}
const test: func = () => { // OK
return {
age: 11,
name: '12',
hei: 123
}
}
Enums
enum Status {
Ready,
Waiting,
}
enum Color {
Red,
Blue,
Green,
}
let status = Status.Ready; // 在定义的时候status的类型被推算出为 Status.Ready
status = Color.Green; // Error
Classes
When comparing two objects of a class type, only members of the instance are compared. Static members and constructors do not affect compatibility
class Animal {
feet: number;
constructor(name: string, numFeet: number) {}
}
class Size {
feet: number;
constructor(numFeet: number) {}
}
let a: Animal;
let s: Size;
a = s; // OK
s = a; // OK