Ts中逆变和协变—例子生动看完即懂

简介: Ts中逆变和协变—例子生动看完即懂

在了解Ts的逆变和协变之前,我们先了解一下什么叫做鸭子类型


鸭子类型



如果一只鸟走路像鸭子 ,游泳也像,做什么都像,那么这只鸟就可以成为鸭子类型。

我们不用关心鸭子的定义是什么,只要符合我们通常意义上的认知,那么他就是这个物体。

在 TypeScript中,只要对象符合定义的类型约束,那么我们就可以视为他是。


协变



协变,又可以称为鸭子类型


interface A {
    name:string
    age:number
}
interface B {
    name:string
    age:number
    sex:string
}
let a:A = {
    name:"老墨我想吃鱼了",
    age:33,
}
let b:B = {
    name:"老墨我不想吃鱼",
    age:33,
    sex:"女"
}
a = b


接口A中有name和age属性,接口B有name,age和sex属性。 当我们将b赋值给a的时候,因为B类型是A类型的子集,所以我们可以将B赋值给A


回到我们的鸭子类型上,我们可以将A理解成那个鸭子,B理解成那只鸟。因为B中的name像A,B中的age像A,即B满足A的所有特性,所以B就是A类型,可以正确赋值。换句大白话讲,就是B类型只能多,不能少,才可以正确赋值。


我们再从集合的角度来理解协变。刚刚我们提到B是A的子集,相信一定会有同学出来反驳,明明,B的属性比A多,A才是B的子集!


这里的集合概念和我们平时认知的不太一样。大家可以换个角度想,接口中的属性可以相当于我们的限制条件。就拿我们找工作举例子,熟悉React的应聘者是一个集合A,当我们增加我们的招聘要求时,不仅熟悉React,还要熟悉node,满足这两个招聘条件的应聘者又构成一个集合B。那么集合B是不是集合A的子集呢?


相信大家对协变已经有自己的理解了吧!


逆变



逆变一般发生于函数的参数上面


interface A {
    name:string
    age:number
}
interface B {
    name:string
    age:number
    sex:string
}
let a:A = {
    name:"老墨我想吃鱼了",
    age:33,
}
let b:B = {
    name:"老墨我不想吃鱼",
    age:33,
    sex:"女"
}
a = b
let fna = (params:A) => {
}
let fnb = (params:B) => {
}
fna = fnb //错误
fnb = fna //正确


我们刚刚说到B是A的子集, 但是我们在函数的参数中使用A/B类型,为什么和刚刚的结果不一样呢? 只能将fna赋值给fnb


小栗子又来了

我们在使用函数进行赋值的时候,fnb = fna 。当我们赋完值调用fnb时,实际上调用的是fna


let a = () => {
    console.log('a')
}
let b = () => {
    console.log(b)
}
b = a;
b() //a


所以fna中params:A又充当了我们的主类型,B是我们的子类型,B是A的子集,所以赋值成功!


双向协变



tsconfig中strictFunctionTypes 设置为false 支持双向协变 fna fnb 随便可以来回赋值,但是不推荐这么设置。


通过tsc --init生成配置项


fna = fnb
fnb = fna


image.png

目录
相关文章
|
7月前
|
存储 安全 前端开发
终于搞懂啦!ts泛型是这样使用的呀
使用泛型可以编写通用的函数或类,以适应多种类型的数据。例如,Array 类型提供了通用的泛型数组容器,可以用于存储不同类型的元素。
|
JavaScript 索引
typescript(ts) 类型演算,类型推导
我们都知道,ts 具有类型推导,并且可以很好的进行智能的类型推导。但是如果我们想要手动的来进行类型推导 —— 通过已知的类型来推断另一个类型,那么这个需要怎么做呢?
typescript(ts) 类型演算,类型推导
ts重点学习8-泛型类定义
ts重点学习8-泛型类定义
48 0
ts重点学习5-泛型接口
ts重点学习5-泛型接口
51 0
ts重点学习5-泛型接口
ts重点学习78-泛型接口
ts重点学习78-泛型接口
66 0
ts重点学习78-泛型接口
ts重点学习77-泛型接口
ts重点学习77-泛型接口
45 0
ts重点学习77-泛型接口
ts重点学习80-泛型类笔记
ts重点学习80-泛型类笔记
50 0
ts重点学习6-泛型接口笔记
ts重点学习6-泛型接口笔记
43 0