首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
开篇:用正确的方式学习 TypeScript
打造 TypeScript 的开发环境
TypeScript中的原始类型与对象类型
TypeScript中的字面量类型与枚举
TypeScript中的函数重载与面向对象
TypeScript的内置类型:any、unknown、never 与类型断言
TypeScript 类型工具
TypeScript 中无处不在的泛型
TypeScript 类型系统层级:从 Top Type 到 Bottom Type
TypeScript 类型里的逻辑运算:条件类型与 infer
TypeScript 中的内置工具类型基础
TypeScript 反方向类型推导:用好上下文相关类型
TypeScript 函数类型:协变与逆变的比较
TypeScript中类型编程与类型体操的意义
TypeScript模板字符串类型
TypeScript模板字符串工具类型进阶
TypeScript类型声明、类型指令与命名空间
在 React 中愉快地使用 TypeScript:内置类型与泛型坑位
让 ESLint 来约束你的 TypeScript 代码:配置与规则集介绍
TypeScript装饰器与反射元数据
TypeScript控制反转与依赖注入
TSConfig 全解(上):构建相关配置
TSConfig 全解(下):检查相关、工程相关配置
当前位置:
首页>>
技术小册>>
TypeScript入门指南
小册名称:TypeScript入门指南
TypeScript 中,函数类型有着协变和逆变两种关系。这两种关系是非常重要的概念,尤其是在设计接口和泛型的时候,深入理解它们可以帮助我们更好地使用 TypeScript。本章节将会介绍协变和逆变的概念,并通过代码示例来展示它们的应用。 -------------------- **1、协变** 协变是指一个类型 S 可以被赋值给另一个类型 T,如果 S 比 T 更具体(更窄)。这个概念在函数类型中的应用,可以理解为函数参数的类型可以是参数类型的子类型。换句话说,如果我们将一个接受类型为 Animal 的函数赋值给一个接受类型为 Cat 的函数,那么就是在进行协变。 我们可以通过下面的代码示例来展示协变: ```javascript interface Animal { name: string; } interface Cat extends Animal { meow(): void; } function takeAnimal(animal: Animal) { console.log(`Taking care of ${animal.name}`); } function takeCat(cat: Cat) { console.log(`Taking care of ${cat.name}`); cat.meow(); } takeAnimal = takeCat; // 协变 ``` 在上面的代码中,我们定义了两个函数 takeAnimal 和 takeCat,它们接受不同的参数类型。takeAnimal 接受类型为 Animal 的参数,而 takeCat 接受类型为 Cat 的参数。然后,我们将 takeCat 赋值给 takeAnimal,这是一种协变的情况。因为 Cat 是 Animal 的子类型,所以接受 Cat 的函数可以被用作接受 Animal 的函数。 **2、逆变** 逆变是指一个类型 S 可以被赋值给另一个类型 T,如果 S 比 T 更加抽象(更宽)。在函数类型中的应用,可以理解为函数参数的类型可以是参数类型的超类型。换句话说,如果我们将一个接受类型为 Cat 的函数赋值给一个接受类型为 Animal 的函数,那么就是在进行逆变。 我们可以通过下面的代码示例来展示逆变: ```javascript interface Animal { name: string; } interface Cat extends Animal { meow(): void; } function takeAnimal(animal: Animal) { console.log(`Taking care of ${animal.name}`); } function takeCat(cat: Cat) { console.log(`Taking care of ${cat.name}`); cat.meow(); } takeCat = takeAnimal; // 逆变 ``` 在上面的代码中,我们将 takeAnimal 赋值给 takeCat,这是一种逆变的情况。因为 Animal 是 Cat 的超类型,所以接受 Animal 的函数可以被用作接受 Cat 的函数。 **3、逆变和协变在泛型中的应用** 逆变和协变不仅仅适用于函数类型,它们还可以应用于泛型类型。我们可以使用 in 表示逆变,使用 out 表示协变。在 TypeScript 中,逆变和协变在泛型中的应用是非常常见的,它们可以帮助我们更好地定义通用的接口和函数。 我们可以通过下面的代码示例来展示泛型中的逆变和协变: ```javascript interface Animal { name: string; } interface Cat extends Animal { meow(): void; } interface Box<T> { value: T; } let animalBox: Box<Animal> = { value: { name: "Fluffy" } }; let catBox: Box<Cat> = { value: { name: "Whiskers", meow() {} } }; function takeAnimalBox(box: Box<Animal>) { console.log(`Taking care of ${box.value.name}`); } function takeCatBox(box: Box<Cat>) { console.log(`Taking care of ${box.value.name}`); box.value.meow(); } takeAnimalBox = takeCatBox; // 逆变 catBox = animalBox; // 协变 ``` 在上面的代码中,我们定义了一个泛型类型 Box<T>,它有一个 value 属性,类型为 T。然后,我们定义了两个函数 takeAnimalBox 和 takeCatBox,它们接受 Box 类型的参数。最后,我们将 takeCatBox 赋值给 takeAnimalBox,这是一种逆变的情况。同时,我们也将 animalBox 赋值给 catBox,这是一种协变的情况。 **小结** 在 TypeScript 中,函数类型有着协变和逆变两种关系,这两种关系是非常重要的概念。协变和逆变可以应用于函数类型和泛型类型,帮助我们更好地定义通用的接口和函数。理解协变和逆变的概念可以帮助我们更好地使用 TypeScript,并避免一些潜在的错误。
上一篇:
TypeScript 反方向类型推导:用好上下文相关类型
下一篇:
TypeScript中类型编程与类型体操的意义
该分类下的相关小册推荐:
TypeScript 全面进阶指南
TypeScript开发实战
剑指TypeScript