TypeScript如何定义以对象属性值为另一属性泛型参数的泛型接口
问题原因
原有写法不生效的核心逻辑:
- 当你不显式传入泛型参数、直接给变量标注
SpecificConfig类型时,TypeScript会直接使用泛型默认值ConfigUnion['id'](所有id的联合类型)填充泛型位,不会根据对象字面量中id的实际值反向窄化泛型参数。 - 此时
ParametersOfConfig<Id>计算的是所有Config类型的公共属性,自然只会得到所有接口共有的id键。
解决方案
根据使用场景二选一即可:
方案1:定义为判别式联合类型(完全匹配预期需求)
不需要保留对外暴露的泛型参数,直接遍历所有Config分支生成合法配置的联合类型,TypeScript会自动以id作为判别键做类型窄化:
type SpecificConfig = { [K in ConfigUnion['id']]: { id: K; iterable: Array<Partial<keyof Extract<ConfigUnion, { id: K }>>>; } }[ConfigUnion['id']];
使用时无需手动传入泛型参数,类型校验会自动生效:
const configInstance: SpecificConfig = { id: 'Config1.id', // 对应Config1的id值 iterable: ['Config1Prop1', 'Config1Prop2'] // 此处仅允许传入Config1的属性键,传入其他Config的属性会直接抛出类型错误 };
方案2:泛型辅助函数(适合需要复用泛型逻辑的场景)
如果需要保留泛型扩展能力,不要直接给变量标注带默认值的泛型类型,通过泛型构造函数触发自动推断:
const createSpecificConfig = <Id extends ConfigUnion['id']>(config: { id: Id; iterable: Array<Partial<keyof Extract<ConfigUnion, { id: Id }>>>; }) => config;
使用时不需要额外标注类型、不需要手动传泛型,类型推导会自动完成:
const configInstance = createSpecificConfig({ id: 'Config1.id', iterable: ['Config1Prop1'] // 自动匹配Config1的属性键范围,校验逻辑正常 });
内容的提问来源于stack exchange,提问作者Mickey Barron
相关产品推荐
相关产品推荐

