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

TypeScript中reduce累加器推断为never类型的问题及解决方法

TypeScript reduce累加器赋值报错:类型'string | number'无法赋值给类型'never'

问题代码

const getObjectKeys = Object.keys as <T extends object>(obj: T) => Array<keyof T>;

interface AB {
    a: string;
    b: number;
}
export function test(config: AB) {
    getObjectKeys(config).reduce((memo, key) => {
        memo[key] = config[key]; // 此处触发报错
        return memo;
    }, {} as AB);
}

报错信息

memo[key] - TS2322: 类型'string | number'无法赋值给类型'never'。类型'string'无法赋值给类型'never'。


为什么会报错?

你用{} as AB把空对象强制断言成AB类型,但空对象本身并不具备AB的任何属性,TypeScript的类型检查能识别这个逻辑矛盾。在reduce回调里,key的类型是'a' | 'b',config[key]的类型是string | number,但空对象的属性初始状态被判定为never(因为这些属性根本不存在),所以赋值时就会触发类型不匹配的错误。

用(memo as any)[key]能运行是因为any直接绕过了所有类型检查,但这会丢失TypeScript的类型安全优势,不推荐这么做。


正确的解决方法

方法1:用Partial作为累加器的中间类型

Partial<AB>表示所有属性都是可选的,刚好匹配reduce过程中逐步填充属性的场景,最后再把结果断言为完整的AB类型:

export function test(config: AB) {
    return getObjectKeys(config).reduce((memo, key) => {
        memo[key] = config[key];
        return memo;
    }, {} as Partial<AB>) as AB;
}

方法2:用Record类型初始化累加器

通过Record<keyof AB, string | number>明确累加器的键和值的类型范围,最后再断言为AB:

export function test(config: AB) {
    return getObjectKeys(config).reduce((memo, key) => {
        memo[key] = config[key];
        return memo;
    }, {} as Record<keyof AB, string | number>) as AB;
}

方法3:初始化完整的AB对象(推荐,类型最安全)

如果AB的属性有合理的默认值,直接创建一个符合AB类型的初始对象,不需要任何额外断言:

export function test(config: AB) {
    return getObjectKeys(config).reduce((memo, key) => {
        memo[key] = config[key];
        return memo;
    }, { a: '', b: 0 });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 02:05:14