TypeScript:基于Schema转换对象时类型报错求助
问题分析与解决方案
你遇到的类型错误根源在于:TypeScript无法在循环中自动推断出key、validation[key]和obj[key]之间的类型关联。具体来说,Object.entries(data)返回的key会被推断为宽泛的string类型,而非keyof T,导致validation[key]的类型被拓宽为keyof TypeMap | undefined,同时obj[key]的类型也无法与transformValue的返回值类型匹配,最终触发类型不兼容报错。
修复后的完整代码
interface TypeMap { boolean: boolean; string: string; } type Transformers = { [K in keyof TypeMap]: (value: string) => TypeMap[K] } const transformers: Transformers = { string: (value: string) => value, boolean: (value: string) => Boolean(value), }; function transformValue<K extends keyof Transformers>(value: FormDataEntryValue, type: K): TypeMap[K] { return transformers[type](String(value)); } // 调整data的类型,确保键与T严格对应 function transform<T extends object>(data: Record<keyof T, string>, validation: Record<keyof T, keyof TypeMap>): Partial<T> { const obj: Partial<T> = {}; // 断言键类型为keyof T,明确类型关联 for(const [key, value] of Object.entries(data) as Array<[keyof T, string]>) { const type = validation[key]; // 断言返回值与T[key]类型匹配 obj[key] = transformValue(value, type) as T[key]; } return obj; } interface ExampleFormFields { lorem: string; ipsum: boolean; } const formData = { lorem: 'lorem', ipsum: 'true' }; const exampleFormValidation: Record<keyof ExampleFormFields, keyof TypeMap> = { lorem: 'string', ipsum: 'boolean' }; const transformed = transform<ExampleFormFields>(formData, exampleFormValidation);
关键修改说明
- 约束
data的键类型:将data的类型从Record<string, string>改为Record<keyof T, string>,确保传入的data键完全匹配目标类型T的键,避免多余或缺失键导致的类型歧义。 - 明确循环中键的类型:通过
as Array<[keyof T, string]>断言Object.entries的返回值类型,让TypeScript知道循环中的key属于keyof T集合,而非宽泛的string。 - 类型断言匹配返回值:添加
as T[key]断言,帮助TypeScript确认transformValue的返回值与obj[key]的类型完全兼容。
为什么原代码报错?
TypeScript中Object.entries的键默认被推断为string(因为对象键在运行时本质都是字符串),而validation的键是keyof T,这会导致validation[key]被推断为keyof TypeMap | undefined(存在key不在validation中的可能),同时obj[key]的类型是T[keyof T] | undefined,两者无法与transformValue的返回值类型直接匹配,最终触发类型错误。
内容的提问来源于stack exchange,提问作者rwacarter
相关产品推荐
相关产品推荐

