TypeScript两种条件类型映射方法的差异及语法疑问
TypeScript字符串类型字段过滤方法差异及映射键语法说明
假设我要过滤某个类型的所有字符串类型字段,可编写如下代码:
// 将值的映射类型设为never type StringKeysFilterV1<T> = { [K in keyof T]: T[K] extends string ? K : never }; // 将映射键设为never type StringKeysFilterV2<T> = { [K in keyof T as T[K] extends string ? K : never]: K };使用方式如下:
class MyClass { public numberField: number = 0; public stringField: string = ''; public booleanField: boolean = false; } type Key1 = StringKeysFilterV1<MyClass>[keyof MyClass]; // 结果:"stringField" type Key2 = keyof StringKeysFilterV2<MyClass>; // 结果:"stringField"请问这两种方法有何差异?是否完全相同?另外,我未找到文档说明映射键
[]内[K in keyof T as X extends Y ? A : B]语句的用法,该用法的相关关键词是什么?
两种过滤方法的差异
这两种方法不完全相同,核心差异体现在实现逻辑和边缘场景表现上:
- V1实现逻辑:先为原类型的所有键创建完整映射,符合字符串类型条件的键对应值为键名类型,不符合的对应值设为
never。最后通过[keyof T]索引访问时,TypeScript会自动忽略值为never的条目,从而得到目标键名。 - V2实现逻辑:直接在遍历键的阶段完成筛选——通过
as子句决定键的去留,返回never的键会被直接排除在最终映射类型的键集合之外,最终直接取keyof就能得到筛选后的结果。
可选键场景的差异
当原类型包含可选键时,两者表现会出现明显区别:
type MyType = { num: number; str?: string; }
StringKeysFilterV1<MyType>[keyof MyType]的结果为"str" | undefined(可选键的类型是string | undefined,不满足extends string的判断,对应值为never,但索引访问可选键时会带上undefined)。keyof StringKeysFilterV2<MyType>的结果为"str"(as子句能正确识别可选键的类型分支,只要存在string类型就保留该键)。
映射键条件语法的相关关键词
你提到的[K in keyof T as X extends Y ? A : B]属于TypeScript的映射类型重映射(Mapped Type Remapping),核心关键词是**as子句或映射类型键重映射**。
这种语法允许在遍历类型键的过程中,对键进行修改、筛选或转换:返回never的键会被从最终映射类型中移除,返回其他值则作为新的键名使用。
内容的提问来源于stack exchange,提问作者jayatubi
相关产品推荐
相关产品推荐

