TypeScript:如何筛选含password属性值的键生成联合类型?
TypeScript 提取值包含指定属性的对象键
给定如下TypeScript对象类型SomeParamList,其中键为字符串类型,值可能是undefined或任意键值对对象。需要定义一个联合类型,只保留那些值**至少包含{ password: string }**的对象键。
type SomeParamList = { FirstScreen: undefined, SecondScreen: {someParam: string} ThirdScreen: {password: string, name: string}, FourthScreen: {password:string} } type KeysWithPass = ... // ^? "ThirdScreen" | "FourthScreen"
尝试过的代码(未达到预期)
我尝试了以下类型定义:
type Narrowed<T, U> = { [K in keyof T]: T[K] extends U ? T[K] : never; };
这个类型会返回一个对象类型,不符合条件的属性类型会被设为never,但对它使用keyof时,仍然会返回原类型的所有键,达不到只保留目标键的效果。
正确实现方式
要实现只提取符合条件的键,可以利用TypeScript的条件类型结合映射类型的键过滤能力,直接在映射类型中筛选出符合条件的键,而不是仅修改属性类型。
type KeysWithPass<T> = { [K in keyof T]: T[K] extends { password: string } ? K : never; }[keyof T]; // 使用示例 type SomeParamList = { FirstScreen: undefined, SecondScreen: {someParam: string} ThirdScreen: {password: string, name: string}, FourthScreen: {password:string} } type Result = KeysWithPass<SomeParamList>; // Result 的类型是 "ThirdScreen" | "FourthScreen"
原理说明
- 先通过映射类型遍历
T的所有键K,对每个键对应的类型T[K]做判断:如果T[K]是包含password: string的对象,就保留键K,否则把该位置设为never。 - 最后用
[keyof T]索引访问这个映射后的类型,此时never类型的键会被自动排除,剩下的就是符合要求的键的联合类型。
如果需要更通用的版本(支持传入任意要匹配的属性类型),可以封装成工具类型:
type KeysWithProperty<T, Prop extends Record<string, unknown>> = { [K in keyof T]: T[K] extends Prop ? K : never; }[keyof T]; // 使用示例 type Result = KeysWithProperty<SomeParamList, { password: string }>; // 同样得到 "ThirdScreen" | "FourthScreen"
内容的提问来源于stack exchange,提问作者uloco
相关产品推荐
相关产品推荐

