子类型

  • 在集合论中属性更少的是子类型
  • 在类型中属性更多的是子类型
  • 子类型比父类型更具体

协变

父亲类型:interface person {}
子类型:interface chinese extens person{ … }
转变成数组之后,对于父类型的变量,依然只会去子类型中一定有的那些属性。
对于type makeArrary<T>=T[]这个类型构造器来说,他就是协变的。

逆变

  1. let visitAnimal = (animal: Animal) => void;
  2. let visitDog = (dog: Dog) => void;
  3. let visitAnimal = (animal: Animal) => {
  4. animal.age
  5. }
  6. let visitDog = (dog: Dog) => {
  7. dog.age
  8. dog.bark()
  9. }
  10. visitAnimal = visitDog
  11. let animal = { age: 5 }
  12. visitAnimal(animal) // ❌ //animal.back不存在
  13. visitDog = visitAnimal
  14. let dog ={
  15. age:1,
  16. back:()=>{}
  17. }
  18. visitDog(dog) // 合理 因为传入的dog会比animal更加具体
  19. 在调用这个类型构造器,父子关系逆转了。
  20. type MakeFunction<T> = (arg: T) => void

双向协变

在 TypeScript 中,由于灵活性等权衡,对于函数参数默认的处理是 双向协变 的。在开启了 tsconfig 中的 strictFunctionType 后才会严格按照 逆变 来约束赋值关系。