Typescript 中的逆变与协变

Typescript 中的逆变与协变

概念:协变和逆变都是术语,前者指能够使用比原始指定的派生类型的派生程度更大(更具体的)的类型,后者指能够使用比原始指定的派生类型的派生程度更小(不太具体的)的类型 。 泛型类型参数支持协变和逆变,可在分配和使用泛型类型方面提供更大的灵活性。

一、typescript 协变

示例

type parent = string|number|boolean

type child = string|boolean

type test = child extends parent ? true:false
// test 的类型是true
let a:child = true;
let b:parent = 1;
a = b; // 报错 Type 'number' is not assignable to type 'child'.
b = a; // 不报错

结论: 如图中代码所示 child类型可以继承parent类型(child 为 parent的子类) 当我们创建两个变量 a = true、b = 1并且分别赋给它们child和parent类型的时候。如果这这时想把b赋值给a,就会报类型错误(Type ‘number’ is not assignable to type ‘child’.),说child里面没有
number属性,而a赋值给b的时候不报错,说明变量赋值只能给它赋一个相同或者更具体的类型,这种特性称之为协变

二、typescript 逆变

示例

type parent = string|number|boolean

type child = string|boolean

type fun1 = (a:child)=> null;
type fun2 = (a:parent)=> null;
type test = fun2 extends fun1?true:false
// test 的类型是true
let fun11:fun1 = (a:child) => null;
let fun22:fun2 = (a:parent) => null;

fun11 = fun22; // 成功赋值
fun22 = fun11; // 报错 Type '(a: child) => null' is not assignable to type '(a: parent) => null'.

结论: 如图中代码所示 第一个方法类型中的参数类型为child,第二个方法中的参数类型为parent,test 的类型为true,说明了fun2类型可以继承fun1类型,且当我们实现两个这样的方法fun11和fun22以后,同样也只能由fun22给fun11赋值。

这样引出来一个问题:明明child继承自parent,为什么只能由参数为parent
的函数赋值给参数为child类型的函数呢?

案例:

type parent = string|number
type child = string

type fun1 = (a:child)=> void;
type fun2 = (a:parent)=> void;

let fun11:fun1 = (a:child) => {
  switch (typeof a) {
    case 'string':
      console.log('string');
      break;
    default:
      console.log('default');
      break;
  }
};
let fun22:fun2 = (a:parent) => {
  switch (typeof a) {
    case 'string':
      console.log('string');
      break;
    case 'number':
      console.log('number');
      break;
    default:
      console.log('default');
      break;
  }
};

fun11 = fun22; // 成功赋值
fun22 = fun11; // 报错 Type 'number' is not assignable to type 'string'.

图中代码不难看出: 子类型的方法只能处理string,而父类型的方法不仅可以处理string,还能处理number。如果我们给fun11 赋值 fun22,fun22本来就能处理string和number,因此只给它赋值string类型的参数也不会有什么问题,反过来给fun11只能处理string类型的参数,但如果给fun22赋值fun11就有可能会往参数中传递number 类型,这样就会报错,这种逆向派生类型赋值的特性我们称之为逆变。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值