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

升级Angular17遇TypeScript错误:'resRemarks'属性不存在于string类型

问题描述

将Angular 12项目升级到Angular 17后,原代码出现TypeScript类型错误:代码通过this.pmlaCheck[d.results](d是this.pmlaDbData数组元素,results存储PmlaCheck接口的属性名,如"cibilSfcResults")访问对应子对象并读取resRemarks属性时,TypeScript提示该属性不存在于string类型。已通过d.results as keyof PmlaCheck解决索引类型错误,现需解决属性访问的类型报错。

相关接口定义:

export interface PmlaCheck {
  _id?: string;
  cibilSfcResults: CibilSfcResults;
  mcxActionApResults: McxActionApResults;
  mcxDefaultersResults: McxDefaultersResults;
  // 其他省略属性...
}

export interface CibilSfcResults {
  fnCheck: CibilSfc[];
  fmCheck: CibilSfc[];
  flCheck: CibilSfc[];
  mlCheck: CibilSfc[];
  fmlCheck: CibilSfc[];
  panCheck: CibilSfc[];
  remarks: string;
  resRemarks: string;
}

报错信息(已翻译):

类型“string | number | boolean | Date | SebiList[] | UnList[] | UkSanctions[] | CibilSfcResults | McxActionApResults | ... 28 more ... | [...]”上不存在属性“resRemarks”。
  类型“string”上不存在属性“resRemarks”。ts(2339)
解决方案

1. 类型守卫(推荐)

先定义一个类型守卫函数,用于判断当前值是否包含resRemarks属性:

function hasResRemarks(obj: unknown): obj is { resRemarks: string } {
  return typeof obj === 'object' && obj !== null && 'resRemarks' in obj;
}

在业务代码中使用守卫做类型判断:

const targetObj = this.pmlaCheck[d.results as keyof PmlaCheck];
if (hasResRemarks(targetObj)) {
  // 此处TypeScript会自动推断targetObj包含resRemarks属性
  const remarks = targetObj.resRemarks;
  // 执行后续逻辑
}

2. 精准类型断言

如果你能确定当前d.results对应的属性必然是包含resRemarks的子类型,可以直接做精准断言:

// 通用断言(适用于所有带resRemarks的子接口)
const remarks = (this.pmlaCheck[d.results as keyof PmlaCheck] as { resRemarks: string }).resRemarks;

// 针对特定子接口的断言(更精准)
const remarks = (this.pmlaCheck[d.results as keyof PmlaCheck] as CibilSfcResults).resRemarks;

3. 重构接口定义优化类型约束

如果多个子接口都包含resRemarks和remarks属性,先提取共享接口:

// 定义共享接口
export interface HasResRemarks {
  resRemarks: string;
  remarks: string;
}

// 修改子接口继承共享接口
export interface CibilSfcResults extends HasResRemarks {
  fnCheck: CibilSfc[];
  fmCheck: CibilSfc[];
  flCheck: CibilSfc[];
  mlCheck: CibilSfc[];
  fmlCheck: CibilSfc[];
  panCheck: CibilSfc[];
}

// 其他包含resRemarks的子接口同理继承HasResRemarks

然后筛选出PmlaCheck中属于HasResRemarks类型的键:

type PmlaCheckKeysWithResRemarks = {
  [K in keyof PmlaCheck]: PmlaCheck[K] extends HasResRemarks ? K : never;
}[keyof PmlaCheck];

后续代码中用这个类型做断言,就能直接访问resRemarks:

const targetKey = d.results as PmlaCheckKeysWithResRemarks;
const remarks = this.pmlaCheck[targetKey].resRemarks; // 无类型报错

4. 可选链临时解决(不推荐长期使用)

如果允许resRemarks不存在时取默认值,可结合可选链和空值合并临时规避报错,但会丢失类型检查:

const remarks = (this.pmlaCheck[d.results as keyof PmlaCheck] as any)?.resRemarks ?? '';

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 09:21:14