TS中infer与extends的使用

前言


😳在TS进行类型之间的转换和判断的时候经常用到两个东西,分别是inferextends,这篇文章我们就来讲解下他们的基本使用。

一.extends使用


🐸在泛型中,我们可以使用 extends 关键字来约束传入的泛型参数必须符合要求。关于 extendsA extends B 意味着 A 是 B 的子类型,这里我们暂时只需要了解非常简单的判断逻辑,也就是说 A 比 B 的类型更精确,或者说更复杂。具体来说,可以分为以下几类。

😳更精确,如字面量类型是对应原始类型的子类型,即 'ddd' extends string599 extends number 成立。类似的,联合类型子集均为联合类型的子类型,即 1、 1 | 2 是 1 | 2 | 3 | 4 的子类型。

🐔更复杂,如 { name: string } 是 {} 的子类型,因为在 {} 的基础上增加了额外的类型,基类与派生类(父类与子类)同理。

二.infer使用


👽假设我们有一个类型 Person,包含一个 name 属性和一个 age 属性:

ts 复制代码
type Person = {
  name: string;
  age: number;
};

😳现在,我们想要从 Person 类型中提取出 name 属性的类型。这时,我们可以使用 infer 关键字来实现:

ts 复制代码
type ExtractName<T> = T extends { name: infer Name } ? Name : never;

🐔在上述代码中,我们定义了一个条件类型 ExtractName,它接受一个类型 T 作为参数。在条件类型中,我们使用 T extends { name: infer Name } 来检查 T 是否具有 name 属性,并将该属性的类型推断为 Name

🦔现在,我们可以使用 ExtractName<Person> 来提取 Person 类型中的 name 属性的类型:

ts 复制代码
type NameType = ExtractName<Person>; // 推断 NameType 的类型为 string

🦥在这个例子中,NameType 被推断为 string,因为 Person 类型的 name 属性的类型是 string

三.映射类型


😬对象、class 在 TypeScript 对应的类型是索引类型(Index Type),那么如何对索引类型作修改呢?

答案是映射类型

ts 复制代码
typescript
复制代码
type MapType<T> = {
  [Key in keyof T]?: T[Key]
}

keyof T 是查询索引类型中所有的索引,叫做索引查询

T[Key] 是取索引类型某个索引的值,叫做索引访问

in 是用于遍历联合类型的运算符。

五.提取元组第一个元素数据类型


ts 复制代码
type First<Tuple extends unknown[]> = Tuple extends [infer T, ...infer R] ? T : never;

首先,我们定义了一个泛型类型 Tuple,它表示一个元组类型。

接着,我们使用条件类型来判断 Tuple 是否符合 [infer T, ...infer R] 的结构。这里使用了元组解构语法,[infer T, ...infer R] 表示一个由至少一个元素 T 和剩余元素 R 组成的元组。

在条件类型的结果部分,如果 Tuple 符合 [infer T, ...infer R] 的结构,那么我们将 T 作为返回类型,表示提取出的第一个元素的类型。

如果 Tuple 不符合 [infer T, ...infer R] 的结构,即为空元组或只有一个元素,那么返回类型将是 never,表示无法提取出第一个元素的类型。

最后,我们使用 First<[1, 2, 3]> 来演示如何使用这个 First 类型。在这个例子中,[1, 2, 3] 是一个元组类型,我们期望提取出第一个元素的类型。根据代码的定义,res 的类型将是 1,即元组 [1, 2, 3] 的第一个元素的类型。

总结起来,这段代码通过条件类型和 infer 关键字,实现了从元组类型中提取出第一个元素的类型。

四.总结


😬extendsinfer会在类型编程中使用的非常频繁,所以非常的重要,一定要掌握使用方法,类型映射我们只需要记住这个结构在需要使用的时候能够想起来即可。

相关推荐
酒尘&6 小时前
JS数组不止Array!索引集合类全面解析
开发语言·前端·javascript·学习·js
学历真的很重要6 小时前
VsCode+Roo Code+Gemini 2.5 Pro+Gemini Balance AI辅助编程环境搭建(理论上通过多个Api Key负载均衡达到无限免费Gemini 2.5 Pro)
前端·人工智能·vscode·后端·语言模型·负载均衡·ai编程
用户47949283569157 小时前
"讲讲原型链" —— 面试官最爱问的 JavaScript 基础
前端·javascript·面试
用户47949283569157 小时前
2025 年 TC39 都在忙什么?Import Bytes、Iterator Chunking 来了
前端·javascript·面试
大怪v8 小时前
【Virtual World 04】我们的目标,无限宇宙!!
前端·javascript·代码规范
狂炫冰美式9 小时前
不谈技术,搞点文化 🧀 —— 从复活一句明代残诗破局产品迭代
前端·人工智能·后端
xw59 小时前
npm几个实用命令
前端·npm
!win !9 小时前
npm几个实用命令
前端·npm
代码狂想家10 小时前
使用openEuler从零构建用户管理系统Web应用平台
前端
dorisrv11 小时前
优雅的React表单状态管理
前端