You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 13:50:43