Typescript如何定义索引签名属性强类型的泛型对象?
结论
- 你期望的写法无法直接实现:TypeScript 是结构类型系统,类型名称仅为开发阶段的标识,编译后会被擦除,不存在
Typename<T>这类可以在类型层面获取泛型参数名称的运算符,无法直接将索引和类型名称做匹配判断。
可行替代方案
方案1:显式传入属性名作为第二泛型参数
完全匹配你要的使用效果,仅需要多传入一个字符串字面量类型的泛型参数,指定你要映射的属性名:
// 类型定义 type ObjectProps<T, Key extends string> = Record<Key, Partial<T>> & Record<string, unknown> // 使用示例 interface Test { prop: string } declare function someDatasource(): any // 显式指定属性名是 'Test' const a: ObjectProps<Test, 'Test'> = someDatasource() const b1 = a.Test // 类型为 Partial<Test> const b2 = b1.prop // 类型为 string | undefined,TS校验合法 // @ts-expect-error 报错:Partial<Test> 不存在 otherProp 属性 const b3 = b1.otherProp const c = a.otherProp // 类型为 unknown
方案2:封装工厂函数简化调用
如果不想每次手写第二泛型参数,可以用工厂函数封装一层,运行时传入属性名自动关联类型:
// 工厂函数定义 function defineObjectProps<T>(key: string) { return (source: unknown) => source as Record<typeof key, Partial<T>> & Record<string, unknown> } // 使用示例 interface Test { prop: string } declare function someDatasource(): any // 只需调用一次工厂函数,后续生成的实例都符合类型要求 const getTestProps = defineObjectProps<Test>('Test') const a = getTestProps(someDatasource()) const b1 = a.Test // 类型为 Partial<Test> const b2 = b1.prop // TS校验合法 // @ts-expect-error 报错 const b3 = b1.otherProp const c = a.otherProp // 类型为 unknown
补充说明
如果要求严格遵循ObjectProps<Test>的单泛型写法,没有任何额外参数,目前TypeScript没有能力支持,这是类型系统的设计限制,没有绕过的方法。
内容的提问来源于stack exchange,提问作者jseto
相关产品推荐
相关产品推荐

