TypeScript泛型TProperties报错:部分键对象不兼容Record类型
TypeScript泛型约束错误分析与修复
你定义的接口和泛型类型如下:
interface MyInterface { Name1: { userId: string } Name2: { bookingId: string } } type TProperties<T extends Record<keyof MyInterface, boolean>> = { [P in keyof T]: P extends keyof MyInterface ? Pick<MyInterface, P> : never }
当你尝试使用TProperties<{ Name1: true }>时出现类型不匹配错误,核心原因是泛型约束强制要求传入的类型必须包含MyInterface的所有键:
Record<keyof MyInterface, boolean>等价于{ Name1: boolean; Name2: boolean },它要求传入的类型必须同时拥有Name1和Name2两个键。而你传入的{ Name1: true }只包含Name1,缺少Name2,不符合约束条件,因此触发报错。
修复方案
方案1:允许传入部分键(保留原调用方式)
使用Partial工具类型将约束改为可选的键值对,这样可以传入任意子集的键:
type TProperties<T extends Partial<Record<keyof MyInterface, boolean>>> = { [P in keyof T]: P extends keyof MyInterface ? Pick<MyInterface, P> : never } // 现在可以正常使用: type Test = TProperties<{ Name1: true }> // Test的类型为 { Name1: { Name1: { userId: string } } }
方案2:直接指定要选择的键(更简洁)
既然你传入布尔值只是为了标记要选择的键,不如直接让泛型参数接收keyof MyInterface的子集,调用更直观:
type TProperties<T extends keyof MyInterface> = { [P in T]: Pick<MyInterface, P> } // 使用方式: type Test = TProperties<'Name1'> // Test的类型为 { Name1: { Name1: { userId: string } } }
如果你的需求是生成包含指定键对应类型的对象,第二种方案更贴合实际场景,避免了冗余的布尔值参数。
内容的提问来源于stack exchange,提问作者nonsequiter
相关产品推荐
相关产品推荐

