函数兼容性判断
例子:
let x = (a: number) => 0;
let y = (b: number, s: string) => 0;
y = x; // OK
x = y; // Error
要查看 x 是否能赋值给 y ,首先看它们的参数列表,然后再检查返回值类型。 x 的每个参数必须能在 y 里找到对应类型的参数。注意的是参数的名字相同与否无所谓,只看它们的类型。 这里, x 的每个参数在 y 中都能找到对应的参数,同时返回值类型也是兼容的,所以允许赋值。
第二个赋值错误,因为 y 有个必需的第二个参数,但是 x 并没有,所以不允许赋值。
类
类有静态部分和实例部分的类型,比较两个类类型的对象时,只有实例的成员会被比较,静态成员和构造函数不在比较的范围内。
泛型
因为 TypeScript 是结构性的类型系统,类型参数只影响使用其做为类型一部分的结果类型。比如:
interface Empty<T> { }
let x: Empty<number>;
let y: Empty<string>;
x = y; // okay, y matches structure of x
上面代码里, x 和 y 是兼容的,因为它们的结构使用类型参数时并没有什么不同。把这个例子改变一下,增加一个成员,就能看出是如何工作的了:
interface NotEmpty<T> {
data: T;
}
let x: NotEmpty<number>;
let y: NotEmpty<string>;
x = y; // error, x and y are not compatible
在这里,泛型类型在使用时就好比不是一个泛型类型。
对于没指定泛型类型的泛型参数时,会把所有泛型参数当成 any 比较。然后用结果类型进行比较,就像上面第一个例子。比如:
let identity = function<T>(x: T): T {
// ...
}
let reverse = function<U>(y: U): U {
// ...
}
identity = reverse; // Okay because (x: any)=>any matches (y: any)=>any
网友评论