TypeScript映射类型问题:接口联合的keyof为何不满足string约束
报错原因
- 这是TS泛型声明阶段的固定检查逻辑:TS在处理未实例化的泛型参数时,不会提前对泛型默认值做精细化窄化。
keyof操作符作用于未约束的泛型类型时,返回的默认类型始终是string | number | symbol联合类型,哪怕你实际定义的Data接口下所有属性键都是字符串类型,在泛型未实例化阶段也不会做这个推断,因此不满足TransformDataKey要求第二个参数必须是string的约束。 - 传入具体参数后推导正确,是因为泛型实例化后
D被明确为Data['A']这个具体类型,此时keyof D可以被准确推断为字符串字面量联合,自然符合约束要求。
正确实现方案
方案1:对泛型键做类型提取
直接提取keyof D中的字符串类型部分,满足参数约束:
type TransformDataKey<V extends string, T extends string> = `--${V}-${T}`; type TransformData< V extends string, K extends keyof Data, D = Data[K] > = { [k in TransformDataKey<V, Extract<keyof D, string>>]: string | number; };
方案2:使用键重映射写法(更简洁)
用TS 4.1+支持的键重映射语法,不需要额外做类型提取,逻辑更直观:
type TransformData< V extends string, K extends keyof Data, D = Data[K] > = { [k in keyof D as `--${V}-${k & string}`]: string | number; };
两种方案都可以正常工作,传入TransformData<'abc', 'A'>时都会得到你预期的类型推导结果。
内容的提问来源于stack exchange,提问作者danikaze
相关产品推荐
相关产品推荐

