TypeScript 'not assignable to typeof never'错误及代码优化问询
解决TypeScript类型错误并优化代码
错误原因分析
- 类型推断不精确:
Object.entries(el)返回的键是string类型,即便断言成keyof ChartData,TypeScript也无法关联键对应的具体值类型,导致初始化数组时无法推断数组的正确类型(number[]或string[])。 - 无效值未处理:
RawData的属性允许null/undefined,直接push会触发类型不兼容错误。 - 重复类型断言:多次使用
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
相关产品推荐
相关产品推荐

