TypeScript 的逆变和协变

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 后才会严格按照 逆变 来约束赋值关系。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值