TypeScript传递键到新对象时报错:如何解决类型不兼容问题?
解决TypeScript对象转换的类型不兼容错误
问题描述
编写了一段TypeScript代码,希望传入键名K、K1,将原对象转换为保留对应键值并添加assignment数组的新对象,但代码中的output出现类型不兼容错误。
原代码
type KOutput<T, K extends keyof T> = { [P in K]: T[P]; } & { assignment: string[]; }; const transform = <Obj, K extends keyof Obj, K1 extends keyof Obj>(key1: K, key2: K1, obj: Obj): KOutput<Obj, K | K1> => { const output: KOutput<Obj, K | K1> = { [key1]: obj[key1], [key2]: obj[key2], assignment: ['test'], } return output; }; transform('key1', 'key2', { key1: 'value1', key2: 'value2' });
错误信息
Type '{ [x: string]: Obj[K] | Obj[K1] | string[]; assignment: string[]; }' is not assignable to type 'KOutput<Obj, K | K1>'. Type '{ [x: string]: Obj[K] | Obj[K1] | string[]; assignment: string[]; }' is not assignable to type '{ [P in K | K1]: Obj[P]; }'.
解决方案
原因分析
TypeScript处理带有动态计算属性的对象字面量时,会将其推断为带有字符串索引签名的类型,而KOutput交叉类型要求必须包含K|K1的精确键,且每个键的类型严格匹配原对象对应值的类型,索引签名类型无法满足这种精确的映射要求,因此出现类型不兼容错误。
修正方法1:使用类型断言
直接将创建的对象断言为目标类型,明确告诉TypeScript该对象符合KOutput的类型约束:
type KOutput<T, K extends keyof T> = { [P in K]: T[P]; } & { assignment: string[]; }; const transform = <Obj, K extends keyof Obj, K1 extends keyof Obj>(key1: K, key2: K1, obj: Obj): KOutput<Obj, K | K1> => { // 使用类型断言指定对象类型 const output = { [key1]: obj[key1], [key2]: obj[key2], assignment: ['test'], } as KOutput<Obj, K | K1>; return output; }; transform('key1', 'key2', { key1: 'value1', key2: 'value2' });
修正方法2:拆分对象创建
先创建包含指定键的基础对象,再合并assignment属性,让TypeScript能准确推断基础对象的类型:
type KOutput<T, K extends keyof T> = { [P in K]: T[P]; } & { assignment: string[]; }; const transform = <Obj, K extends keyof Obj, K1 extends keyof Obj>(key1: K, key2: K1, obj: Obj): KOutput<Obj, K | K1> => { // 先创建包含指定键的基础对象,断言为精确的映射类型 const base = { [key1]: obj[key1], [key2]: obj[key2], } as { [P in K | K1]: Obj[P] }; // 合并基础对象与assignment属性 const output: KOutput<Obj, K | K1> = { ...base, assignment: ['test'], }; return output; }; transform('key1', 'key2', { key1: 'value1', key2: 'value2' });
内容的提问来源于stack exchange,提问作者slim1801
相关产品推荐
相关产品推荐

