TypeScript(十四)变体(协变与逆变)

本文介绍了TypeScript中的变体概念,包括子类型化、赋值兼容性、反身性、传递性,以及协变、逆变、双变和不变的特点。通过示例解释了鸭子类型、函数参数的变体规则,并分析了参数逆变与返回值协变的原因。

目录

前言

"鸭子类型"

子类型化

定义

特点

赋值兼容性

反身性

传递性

协变

逆变

双变

不变

思考

看个例子

原因是什么?

返回值

参数

总结

相关文章


前言

本文收录于TypeScript知识总结系列文章,欢迎指正! 

第一次接触到变体这个概念是在深入理解TypeScript中,类型之间的转换称为变体或者变型,在TS中,类型之间能否互相赋值,会不会报错,安不安全这些都与变体有关。本文将带大家了解ts中的变体

在Java中,每一个类都是一个个体,比如,我们定义了一个Dog和Cat两个类,这二者的结构相同。

// Dog.java
public class Dog {
    String color;
    int age;
}

// Cat.java
public class Cat {
    String color;
    int age;
}
// Main.java
public class Main {
    Dog myCat = new Cat();// cannot convert from Cat to Dog
    Cat myDog = new Dog();// cannot convert from Dog to Cat
    Cat myCat2 = new Cat();// 允许
    Dog myDog2 = new Dog();// 允许
}

此时使用控制变量对其二者进行实例化,可以看到,虽然Dog和Cat的属性相同,都有color以及age属性,但是不能互相声明类型及赋

"鸭子类型"

鸭子类型(duck typing)是一种动态类型机制的编程概念,它指的是一个对象的类型由它能干什么决定,而不是它属于什么类决定,它在运行时就会对对象的类型进行判断。鸭子类型的思想是:如果它看起来像鸭子,游起来像鸭子,叫起来像鸭子,那么它就是鸭子。

TS中的类型检查就是鸭子类型系统,如果两个对象类型拥有相同的属性或方法,那么它们就被认定为是相同类型

我们在TS中实现上面的效果

class Dog {
    color: string
    age: number
}
class Cat {
    color: string
    age: number
}

const dog: Cat = new Dog()// 允许
const cat: Dog = new Cat()// 允许

可以看到,TypeScript和JAVA的模式不同,只要结构相同就可以重复使用类型,这与其他语言不太一样。

子类型化

在学习数学的集合时,一个集合A是另一个集合B的子集,那么A可以被视为B的一个子类型;正方形可以视作矩形的一种子类,因为它继承了矩形的性质,同时又在矩形的基础上增加了一些附加的约束条件

定义

在计算机科学中,我们常说的类的继承是对父类的拓展,而子类型化(Subtyping)是父类型的拓展,它是指一种类型(子类型)是另一种类型(超类型)的一种特殊形式。与继承相同,它可以添加或覆盖超类型的属性和方法。它是较为抽象的拓展方式,没有拓展具体的值,而是拓展类型。超类型经过子类型化操作后的类型产物称为子类型。

特点

赋值兼容性

如果IDog是IAnimal的子类型,那么IDog类型的变量可以赋值给IAnimal类型的变量,举个例子说说

interface IAnimal {
    name: string
}
interface IDog extends IAnimal {
    color: string
}
const animal: IAnimal = {
    name: "阿黄"
}
const dog: IDog = Object.assign(animal, {
    color: "black"
})
const _animal: IAnimal = dog // 可以执行

其中IDog继承自IAnimal,如果使用变量将这两种类型实现,则可以将子类型的变量赋予给父类型的变量。

反身性

任何类型都是它自己的子类型。

interface IAnimal {
    name: string
}
const animal: IAnimal = {
    name: "阿黄"
}
const _anim
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿宇的编程之旅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值