TypeScript函数push操作报never类型TS2345错误的解决方法
TS2345 错误:
Argument of type 'TFootnote' is not assignable to parameter of type 'never' 排查与修复 问题原因
两处问题导致报错:
- 类型定义写法错误:
TCellData中footnotes字段类型写为TFootnote[] | [],这里的[]不会被TS识别为「空的TFootnote数组」,而是被推断为长度固定为0的空元组类型,该类型不允许存入任何值,元素类型为never。TS处理联合类型的push方法时,会将参数类型推断为所有联合成员push参数类型的交集,即TFootnote & never = never,因此传入TFootnote类型参数时会触发类型错误。注意:
TFootnote[]本身就已经包含了空数组的合法情况,不需要额外联合[]类型。 - 逻辑实现不符合预期:代码中
const newObj = obj只是创建了原对象的引用,没有实现「复制对象」的效果,后续修改newObj.footnotes会直接改动原传入的obj对象,产生非预期副作用。
修复方案
- 修正
footnotes字段的类型定义,移除多余的| [];如果字段本身可能为undefined,再添加可选标记?。 - 用对象展开、数组展开的方式实现浅拷贝,避免修改原对象,同时从根源避免
push操作的类型问题。
修复后的完整代码:
export type TFootnote = { item1: string; item2: string; }; export type TCellData = { unitName: string; decimals: number; domain: string; fieldX: string; fieldY: string; // TFootnote[] 本身支持空数组,不需要额外联合[] // 如果字段可能缺失,可写为 footnotes?: TFootnote[] footnotes: TFootnote[]; }; export const justFunction = ( obj: TCellData, footnote: TFootnote ) => { // 浅拷贝对象,同时生成新的footnotes数组,不修改原对象 const newObj: TCellData = { ...obj, footnotes: [...obj.footnotes, footnote] }; return newObj; };
如果业务场景中footnotes确实是可选字段(可能不存在),可以将类型改为footnotes?: TFootnote[],对应代码加空值兜底即可:
export const justFunction = ( obj: TCellData, footnote: TFootnote ) => { const newObj: TCellData = { ...obj, footnotes: [...(obj.footnotes ?? []), footnote] }; return newObj; };
内容的提问来源于stack exchange,提问作者user18119766
相关产品推荐
相关产品推荐

