declare 关键字
在 ts 文件中,我们可以用 declare 来声明一个变量/函数/模块/类。常用于测试类型。
比如我们想要测试一下 readonly array 的功能,我们就可以假设有个 a 是符合这个类型的值:
比如我们想要测试一下类型兼容性:
类型兼容性
类型兼容性(Type compatibility) 分为 subtyping compatibility 和 assignment compatibility 两种。两种类型兼容性几乎没什么差别。下面先介绍一些常见的类型兼容的例子:
对象兼容性
type Named = {
name: string;
}
declare let x: Named;
// y's inferred type is { name: string; location: string; }
let y = { name: "Alice", location: "Seattle" };
x = y;
函数额外参数兼容性
let x = (a: number) => 0;
let y = (b: number, s: string) => 0;
y = x; // OK
x = y; // Error
如果对应位置的参数类型相同,则参数多的函数是参数少的函数的子类型
协变与逆变
declare let x: number
declare let y: 1
x = y; // OK
y = x; // Error: Type 'number' is not assignable to type '1'.
declare let fx : (a: number) => void;
declare let fy : (a: 1) => void;
fx = fy; // Error: Type 'number' is not assignable to type '1'.
fy = fx; // OK
declare let gx : () => number;
declare let gy : () => 1;
gx = gy; // OK
gy = gx; // Error: Type 'number' is not assignable to type '1'.
1 是 number 的子类型,
() => 1 是 () => number 的子类型
(a: 1) => void 是 (a: number) => void 的父类型
我们可以发现, 参数的子类型关系倒过来了,但是返回值位置的子类型关系依旧保留。
所以函数中,参数是逆变的,返回值是协变的。