1. 子类型是父类的超集,因为子类型继承了父类,因为子类型属性更多
举例:
interface Animal {
age: number
}
interface Dog extends Animal {
dark(): void
}
所以在可以赋值性方面,子可以赋值父,但父不可以赋值子
举例
let animal: Animal
let dog: Dog
animal = dog // ✅ok
dog = animal // ❌error! animal 实例上缺少属性 'dark'
2. 逆变(函数参数)
有两个函数
let visitAnimal = (animal: Animal) => void;
let visitDog = (dog: Dog) => void;
let visitAnimal = (animal: Animal) => {
animal.age
}
let visitDog = (dog: Dog) => {
dog.age
dog.bark()
}
错误示例
这个时候 没有dark 方法
visitAnimal = visitDog
let animal = { age: 5 }
visitAnimal(animal) // ❌
正确用例
visitDog = visitAnimal
let animal = { age: 5,dark: () => {} }
visitDog(animal)
当然,在 TypeScript 中,由于灵活性等权衡,对于函数参数默认的处理是 双向协变 的。也就是既可以 visitAnimal = visitDog,也可以 visitDog = visitAnimal。在开启了 tsconfig 中的 strictFunctionType 后才会严格按照 逆变 来约束赋值关系。
文章探讨了在TypeScript中子类型如何作为父类型的超集,以及函数参数的逆变概念。子类型可以赋值给父类型变量,但反之则不行。同时,介绍了逆变在函数参数中的应用,以及启用strictFunctionTypes后对赋值关系的影响。
16





