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

如何在将对象数组合并为数组对象时实现正确TypeScript类型标注

修复TypeScript reduce遍历联合键时的类型错误

你的代码逻辑没问题,但TypeScript的类型推断在处理联合类型的键时,无法自动关联每个键对应的具体值类型,导致出现string | number无法赋值给never的错误。以下是两种可靠的修复方案:

方案一:使用泛型函数明确类型关联

通过泛型函数将每个键的类型具体化,让编译器能识别prev[key]和current[key]的类型匹配关系:

type A = {
    foo: number,
    bar: string
}

type B = {
    [key in keyof A]: Array<A[key]>
}

const a: A[] = [
    {
        bar: '42',
        foo: 42
    },
    {
        bar: '1337',
        foo: 1337
    }
]

// 泛型函数约束键与值的类型对应关系
const pushKeyValue = <K extends keyof A>(acc: B, item: A, key: K) => {
    acc[key].push(item[key]);
};

const b: B = a.reduce((prev, current) => {
    (Object.keys(current) as (keyof A)[]).forEach(key => pushKeyValue(prev, current, key));
    return prev;
}, {
    foo: [],
    bar: []
} as B)

方案二:直接在回调中添加类型断言

如果不想额外定义函数,也可以在push时给数组添加类型断言,明确其对应的值类型:

const b: B = a.reduce((prev, current) => {
    (Object.keys(current) as (keyof A)[]).forEach(key => {
        // 断言数组类型为当前key对应的值类型数组
        (prev[key] as Array<A[typeof key]>).push(current[key]);
    });
    return prev;
}, {
    foo: [],
    bar: []
} as B)

错误原因解析

当key是keyof A的联合类型时,TypeScript会把prev[key]推断为Array<number> | Array<string>,current[key]推断为number | string。此时编译器无法保证current[key]的类型和prev[key]的数组元素类型完全匹配,就会将数组元素类型推断为never(因为number & string不存在交集),从而抛出赋值错误。

泛型函数的方式更推荐,因为它能在不破坏类型安全的前提下,清晰地维护键与值的类型关联,尤其适合属性较多的复杂类型。

内容的提问来源于stack exchange,提问作者s4pfyr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 03:50:40