On this page
keyof操作符类型索引
keyof T如何获取对象类型T的所有键组成的联合类型?举例说明其在实现Pick<T, K extends keyof T>等工具类型中的关键作用
考察点分析
该题主要考察以下核心能力维度:
- TypeScript类型操作符理解:考核对
keyof
类型运算符的运行机制及生成类型的理解 - 工具类型实现原理:通过
Pick
工具类型分析类型约束与映射类型的配合使用 - 类型安全性设计:理解类型约束(
K extends keyof T
)如何确保代码健壮性
具体技术评估点:
keyof
操作符生成联合类型的机制- 泛型约束在工具类型中的应用
- 映射类型与索引访问类型的结合使用
- 类型系统对属性存在性的验证
- 工具类型的类型体操实现思路
技术解析
关键知识点
keyof
> 泛型约束 > 映射类型
原理剖析
keyof
运算符:对对象类型T
进行键名提取,生成其所有键的字符串字面量联合类型。例如:interface Person { name: string; age: number } type Keys = keyof Person; // "name" | "age"
泛型约束:
K extends keyof T
表示类型参数K
必须是T
所有键的子集。类似"字符串集合的白名单"机制,确保类型安全。映射类型:通过
[P in K]: T[P]
结构遍历联合类型K
,配合索引访问类型T[P]
提取原始类型中对应属性的类型,实现属性筛选。
常见误区
- 误认为
keyof any
返回string | number
而非具体键名 - 混淆联合类型与交叉类型在
keyof
中的行为(如联合类型的keyof
会取键的并集) - 忽略
keyof
在接口继承、交叉类型中的复合效果
问题解答
keyof T
通过类型查询机制,将对象类型T
的所有属性键组合成字符串字面量联合类型。例如interface User { id: number; name: string }
时,keyof User
解析为"id" | "name"
。
在Pick<T, K extends keyof T>
中:
- 泛型约束确保
K
只能是T
的合法属性键 - 映射类型
[P in K]: T[P]
遍历选中属性,构造新类型 - 类型安全阻止选择不存在的属性,例如
Pick<User, 'email'>
会直接报错
// 实际源码实现
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
interface Book {
title: string;
price: number;
ISBN: string;
}
type BookPreview = Pick<Book, 'title' | 'price'>;
// 等效于 { title: string; price: number }
解决方案
编码示例
// 实现一个SafePick类型,当属性不存在时fallback到never
type SafePick<T, K extends keyof T> = {
[P in K]: T[P];
};
// 使用示例
interface Config {
env: string;
port: number;
ssl: boolean;
}
type DevConfig = SafePick<Config, 'env' | 'port'>;
/*
等效于:
{
env: string;
port: number;
}
*/
复杂度优化:映射类型编译时完成,无运行时开销。通过keyof
约束确保类型系统提前拦截错误。
深度追问
如何实现反向操作的Omit类型?
- 通过
Exclude<keyof T, K>
排除指定键+映射类型
- 通过
keyof
作用于联合类型时的表现?- 取所有类型键的并集(如
keyof (A | B)
=keyof A | keyof B
)
- 取所有类型键的并集(如
如何获取对象值的联合类型?
- 通过索引类型
T[keyof T]
直接提取
- 通过索引类型
Last updated 06 Mar 2025, 13:07 +0800 .