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

TypeScript 'not assignable to typeof never'错误及代码优化问询

解决TypeScript类型错误并优化代码

错误原因分析

  1. 类型推断不精确:Object.entries(el)返回的键是string类型,即便断言成keyof ChartData,TypeScript也无法关联键对应的具体值类型,导致初始化数组时无法推断数组的正确类型(number[]或string[])。
  2. 无效值未处理:RawData的属性允许null/undefined,直接push会触发类型不兼容错误。
  3. 重复类型断言:多次使用k as keyof ChartData导致代码冗余。

解决方案

步骤1:定义辅助类型明确映射关系

先创建辅助类型,关联RawData和ChartData的类型对应关系,让TypeScript能精准推断:

type DataKey = keyof RawData;
// 提取RawData每个键的非空值类型
type NonNullRawValue<K extends DataKey> = Exclude<RawData[K], null | undefined>;
// 对应ChartData中每个键的数组类型
type ChartDataValue<K extends DataKey> = NonNullRawValue<K>[];

步骤2:封装逻辑避免重复断言

写一个泛型函数封装添加值的逻辑,减少重复断言并提升类型安全性:

function addValueToAcc<K extends DataKey>(acc: ChartData, key: K, value: RawData[K]) {
  // 过滤null/undefined无效值
  if (value == null) return;
  // 初始化数组时明确类型
  if (!acc[key]) {
    acc[key] = [] as ChartDataValue<K>;
  }
  // 此时TypeScript能准确推断acc[key]的类型,push不会报错
  acc[key].push(value);
}

步骤3:重构reduce逻辑

修改原代码,使用封装的函数并修正类型断言:

type ChartData = {
    x?: number[],
    y?: number[],
    z?: string[],
};

type RawData = {
    x: number | null | undefined,
    y: number | null | undefined,
    z: string | null | undefined,
}

const data: RawData[] = [{ x: 1, y: 2, z: "3" }, { x: 4, y: 7, z: "10" }];

const formattedData = data.reduce((acc, el) => {
  // 将Object.entries结果断言为精准的键值对类型
  (Object.entries(el) as [DataKey, RawData[DataKey]][]).forEach(([k, v]) => {
    addValueToAcc(acc, k, v);
  });
  return acc;
}, {} as ChartData);

关键优化点

  • 用DataKey统一键类型,避免重复写keyof ChartData/keyof RawData
  • 泛型函数addValueToAcc封装类型判断和数组初始化逻辑,代码更简洁
  • 过滤null/undefined值,既符合业务逻辑(通常不需要无效数据),又解决类型不兼容问题
  • 精准的类型断言让TypeScript能正确推断数组类型,消除never类型错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 03:06:21