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

Ionic Angular项目中NgRx EntityState的ids.includes()方法参数类型不匹配(number无法赋值给never)问题咨询

解决NgRx EntityState中ids.includes()的类型不匹配问题

这个问题我之前也踩过坑,本质是TypeScript无法正确推断EntityState里ids数组的类型,导致它被判定为never[],所以你传入number类型的invoicePreview.id就会报类型不匹配的错误。下面给你几个可行的解决办法:

方法1:明确实体的ID类型(推荐)

首先确保你的InvoicePreviewModel接口里明确指定了id的具体类型,比如:

export interface InvoicePreviewModel {
  id: number; // 这里明确标记为number类型
  // 其他属性...
}

这样TypeScript就能正确推断EntityState<InvoicePreviewModel>里的ids是number[],includes()方法也就不会再要求never类型的参数了。

方法2:使用NgRx EntityAdapter内置的检查方法

其实NgRx的EntityAdapter已经内置了检查实体是否存在的方法,不用自己手动操作ids数组,既安全又能避免类型问题:

on(InvoicesActions.stateTransitionSuccess, (state, { invoice, invoicePreview }) => {
  let invoices: InvoicesState;
  // 用adapter的hasOne方法替代includes检查
  if (adapterInvoices.hasOne(invoicePreview.id, state.invoices)) {
    invoices = adapterInvoices.updateOne({ id: invoicePreview.id, changes: invoicePreview }, state.invoices);
  } else {
    // 你的其他逻辑
  }
  return {
    ...state,
    loaded: true,
    loading: false,
    selectedInvoice: invoice,
    invoices
  }
}),

方法3:临时类型断言(应急方案)

如果上面的方法暂时没法生效,你可以用类型断言强制告诉TypeScriptids的类型:

if ((state.invoices.ids as number[]).includes(invoicePreview.id)) {
  // ...你的逻辑
}

不过这种方法是绕过类型检查,不如前两种优雅,能不用就尽量不用。

错误原因补充

当你创建EntityState的时候,如果TypeScript无法从你的实体接口或selectId函数里推断出ID的具体类型,就会把ids的类型默认设为never[],这就导致了includes()方法参数类型不匹配的问题。只要让类型系统明确知道ID的类型,这个问题就迎刃而解了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 06:14:10