如何为TypeScript对象的每个属性定义独立泛型类型?
实现每个属性拥有独立泛型的对象类型
嘿,这个问题我之前也踩过坑!TypeScript里确实没法给索引签名单独绑定泛型(你写的[name: string]<T>: MyGeneric<T>这种语法目前不支持),不过有两种很实用的方式能实现你想要的效果——让对象的每个属性都拥有独立的泛型类型:
方式一:用映射类型定义强类型对象
如果你已经知道对象会有哪些属性,可以通过泛型映射类型预先定义每个属性的泛型参数:
interface MyGeneric<T> { value: T } // 泛型接口,T是描述每个属性value类型的对象 interface MyObject<T extends Record<string, unknown>> { [K in keyof T]: MyGeneric<T[K]>; } // 定义具体的对象类型:每个属性的value类型明确 type UserInfo = MyObject<{ username: string; age: number; isVerified: boolean; }>; // 使用示例 const user: UserInfo = { username: { value: "Logan" }, age: { value: 28 }, isVerified: { value: true } }; // 此时user.username.value是string类型,user.age.value是number类型,完全独立
这种方式的好处是类型完全可控,TypeScript会严格检查每个属性的value类型是否符合定义。
方式二:用泛型函数创建动态对象
如果你的对象属性是动态的,不想预先定义所有属性,可以用泛型函数让TypeScript自动推断每个属性的泛型类型:
interface MyGeneric<T> { value: T } // 泛型函数,自动推断传入对象中每个MyGeneric的泛型类型 function createMyObject<T extends Record<string, MyGeneric<any>>>(obj: T): T { return obj; } // 使用示例:TypeScript会自动识别每个属性的value类型 const dynamicObj = createMyObject({ title: { value: "TypeScript Tips" }, views: { value: 1000 }, isFeatured: { value: false } }); // 此时dynamicObj.title.value是string,dynamicObj.views.value是number,类型完全独立
这种方式更灵活,适合属性不固定的场景,而且不需要手动写额外的类型定义。
另外补充一句:如果你只是想表达“任意属性都是MyGeneric<某个类型>”,也可以用Record<string, MyGeneric<unknown>>,但这种方式下每个属性的value类型会被视为unknown,需要手动类型断言,不如上面两种方式实用。
内容的提问来源于stack exchange,提问作者Logan Murphy
相关产品推荐
相关产品推荐

