如何在TypeScript中准确提取对象中指定类型的键联合类型?
解决TypeScript提取特定类型键的联合类型问题
问题分析
你当前的KeysOfType工具类型仅能处理普通属性,无法正确匹配可选属性(类型带undefined)和联合类型属性(包含目标类型的分支),核心原因是T[k] extends U的判断是严格的子类型匹配,而非判断属性类型是否包含目标类型的分支。
解决方案1:提取包含目标类型的键(覆盖前两个预期场景)
使用Extract工具类型判断属性类型中是否存在与目标类型U的交集,若存在则保留键名:
export type KeysOfType<T, U> = { [K in keyof T]: Extract<T[K], U> extends never ? never : K }[keyof T];
验证测试
针对你的Config类型:
type Config = { id: string; optional?: boolean; union: boolean | string; show: boolean; };
KeysOfType<Config, boolean>→'show' | 'optional' | 'union'(符合预期)KeysOfType<Config, string>→'id' | 'union'(符合预期)
解决方案2:提取类型完全匹配的键(覆盖第三个预期场景)
若需要严格匹配属性类型与U完全一致(包括undefined的情况),可以使用双向extends判断类型等价性:
export type KeysOfExactType<T, U> = { [K in keyof T]: T[K] extends U ? (U extends T[K] ? K : never) : never }[keyof T];
验证测试
KeysOfExactType<Config, boolean | undefined>→'optional'(符合预期)
原理说明
Extract<T[K], U>:从属性类型T[K]中提取出可赋值给U的部分,若结果不为never,说明属性类型包含目标类型分支。- 双向
extends判断:T[K] extends U且U extends T[K]确保两个类型完全等价,避免子类型被误匹配。
内容的提问来源于stack exchange,提问作者Rodrigo Novais
相关产品推荐
相关产品推荐

