网站排名优化价格私人网络服务器
在 TypeScript 中,keyof 和 in 是用于类型操作的两个关键工具,常用于处理对象类型的键和属性映射。以下是它们的详细解释和用法示例:
1. keyof 关键字
作用:将对象类型的键提取为联合类型。
语法:keyof T,其中 T 是对象类型。
结果:返回 T 的所有键的联合类型。
示例:
interface Person {name: string;age: number;
}type PersonKeys = keyof Person; // "name" | "age"
典型场景:
- 泛型约束:限制函数参数必须为对象的有效键。
function getValue<T, K extends keyof T>(obj: T, key: K): T[K] {return obj[key]; } - 映射类型的基础:结合
in使用,生成新类型(如Partial<T>)。
特殊情况:
- 空对象:
keyof {}结果为never。 - 原始类型:
keyof string返回String包装对象的属性和方法的联合类型(如"length" | "charAt" | ...)。
2. in 关键字
作用:在映射类型中遍历联合类型的每个成员。
语法:[K in T],其中 T 是联合类型。
结果:为联合类型中的每个成员生成新的属性。
示例:
type Keys = "a" | "b";
type MyObject = {[K in Keys]: string;
};
// 等价于 { a: string; b: string; }
典型场景:
- 工具类型的实现:如
Partial<T>、Readonly<T>。type Partial<T> = {[P in keyof T]?: T[P]; }; - 动态生成类型:根据联合类型创建新对象类型。
3. keyof 和 in 的协作
两者常结合使用,keyof 提供键的联合类型,in 遍历这些键生成新属性。
示例:
interface Config {id: number;path: string;
}type ConfigGetters = {[K in keyof Config as `get${Capitalize<K>}`]: () => Config[K];
};
// 结果:
// {
// getId: () => number;
// getPath: () => string;
// }
4. 其他注意事项
- 索引签名:
若对象有索引签名,keyof会返回索引类型。interface StringMap {[key: string]: number; } type Keys = keyof StringMap; // string | number - 枚举类型:
使用keyof typeof Enum获取枚举的键。enum Direction { Up, Down } type DirectionKeys = keyof typeof Direction; // "Up" | "Down" - 类型保护:
in在值空间用于检查属性存在(JavaScript 特性):if ("name" in obj) {// 类型收窄为包含 name 属性的类型 }
总结
| 关键字 | 作用场景 | 示例 | 结果 |
|---|---|---|---|
keyof | 提取对象键的联合类型 | keyof { a: 1, b: 2 } | "a" | "b" |
in | 遍历联合类型生成属性 | { [K in "x"|"y"]: number } | { x: number; y: number } |
掌握 keyof 和 in 的使用,能显著提升 TypeScript 类型操作的灵活性和类型安全性。
