declare 关键字

在 ts 文件中,我们可以用 declare 来声明一个变量/函数/模块/类。常用于测试类型。

比如我们想要测试一下 readonly array 的功能,我们就可以假设有个 a 是符合这个类型的值:
类型兼容性 - 图1比如我们想要测试一下类型兼容性:
类型兼容性 - 图2

类型兼容性

类型兼容性(Type compatibility) 分为 subtyping compatibilityassignment compatibility 两种。两种类型兼容性几乎没什么差别。下面先介绍一些常见的类型兼容的例子:

对象兼容性

  1. type Named = {
  2. name: string;
  3. }
  4. declare let x: Named;
  5. // y's inferred type is { name: string; location: string; }
  6. let y = { name: "Alice", location: "Seattle" };
  7. x = y;

函数额外参数兼容性

  1. let x = (a: number) => 0;
  2. let y = (b: number, s: string) => 0;
  3. y = x; // OK
  4. x = y; // Error

如果对应位置的参数类型相同,则参数多的函数是参数少的函数的子类型

协变与逆变

  1. declare let x: number
  2. declare let y: 1
  3. x = y; // OK
  4. y = x; // Error: Type 'number' is not assignable to type '1'.
  5. declare let fx : (a: number) => void;
  6. declare let fy : (a: 1) => void;
  7. fx = fy; // Error: Type 'number' is not assignable to type '1'.
  8. fy = fx; // OK
  9. declare let gx : () => number;
  10. declare let gy : () => 1;
  11. gx = gy; // OK
  12. gy = gx; // Error: Type 'number' is not assignable to type '1'.

1 是 number 的子类型,
() => 1 是 () => number 的子类型
(a: 1) => void 是 (a: number) => void 的父类型

我们可以发现, 参数的子类型关系倒过来了,但是返回值位置的子类型关系依旧保留。
所以函数中,参数是逆变的,返回值是协变的