如何在TypeScript泛型接口中定义传入类型的属性类型联合?
TypeScript泛型接口中关联字段与对应属性类型的实现方法
你需要的是让field和fieldTypes的类型形成绑定关系——当field指定为T的某个属性名时,fieldTypes自动对应该属性的类型,而非所有属性类型的无序联合。
先看你的原始代码问题:你定义的genericType中,Key是keyof T的默认值,但field和fieldTypes没有建立关联,使用T[keyof T]只会得到所有属性类型的联合;若原类型T存在可选属性,还会混入undefined类型,这就是触发ts(2322)错误的原因。
正确实现方案
调整泛型接口定义,让Key作为约束于keyof T的泛型参数,同时让fieldTypes的类型严格对应T[Key]:
interface sampleObject { name: fullName; age: number; address: string; } interface fullName { first: string; middle: string; last: string; } interface genericType<T, Key extends keyof T> { field: Key; fieldTypes: T[Key]; }
使用示例
此时field和fieldTypes的类型会严格绑定,TypeScript会自动做类型校验:
// 合法:field为"name",fieldTypes必须匹配fullName类型 const validNameItem: genericType<sampleObject, "name"> = { field: "name", fieldTypes: { first: "John", middle: "M", last: "Doe" } }; // 合法:field为"age",fieldTypes必须是number类型 const validAgeItem: genericType<sampleObject, "age"> = { field: "age", fieldTypes: 30 }; // 非法:field为"address"时,fieldTypes不能传入number类型 const invalidItem: genericType<sampleObject, "address"> = { field: "address", fieldTypes: 123 // 类型错误:不能将类型"number"分配给类型"string" };
自动推断简化写法
如果不想手动指定Key泛型参数,可以通过泛型函数实现自动推断:
function createGenericItem<T, Key extends keyof T>(field: Key, fieldTypes: T[Key]): genericType<T, Key> { return { field, fieldTypes }; } // 自动推断Key为"name",fieldTypes类型为fullName const autoInferName = createGenericItem<sampleObject>("name", { first: "Jane", middle: "A", last: "Smith" }); // 自动推断Key为"address",fieldTypes类型为string const autoInferAddress = createGenericItem<sampleObject>("address", "123 Main St");
关于undefined的说明
如果你的T类型中存在可选属性(比如address?: string),那么T[Key]会包含undefined。若要强制过滤掉undefined,可以将fieldTypes的类型改为Exclude<T[Key], undefined>,但这只适用于明确不需要处理可选属性的场景。
内容的提问来源于stack exchange,提问作者hyltonw
相关产品推荐
相关产品推荐

