逆变协变

林一二2022年02月28日 22:42

父子类

从继承的角度看,子类比父类有更多字段、更多信息。

有更多信息的结构可以赋值给有更少信息的结构:协变 Covariance

允许子类型转换为父类型

  • 'a' | 'b' | 'c' 有三种可能,信息更多,包含的范围更广,可以被用在需要C的地方,可以赋值给后者;而 'a' | 'b' 包含的随机可能更少,所以没法赋值给前者。
  • { a: string, b: string, c: string } 也包含了更多信息,所以可以赋值给 { a: string, b: string }

要求更少信息的结构可以赋值给要求更多信息的结构:逆变 Contravariance

在(函数参数里)允许父类型转换为子类型

  • (arg: a | b) => void 只要求两种信息,所以可以赋值给 (arg: a | b | c) => void;后者要求比较多,没法给前者
  • 为满足逆变,我们可以将其改为:(arg: a & b) => void 只要求两种信息, (arg: a & b & c) => void

不然有可能遇到 Type '"emphasis"' is not assignable to type '"paragraph"'.ts(2345) 的报错。

不变

不变就非常好理解了,就是不允许变型的情况,例如两个参数不完全相同。