TypeScript中如何断言内部对象已定义以修复ESLint报错
问题描述
需要将指定资源转换为如下定义的interface A:
interface A { patientId: string; firstName: string; initials: string[]; lastName: string; }
对应的转换函数实现如下:
public static convert(data: Data) { return { patientId: fhirData.identifier[0].value, firstName: fhirData.name[0].given[0], initials: fhirData.name[0].given.slice(1), lastName: fhirData.name[0].family, }; }
ESLint抛出错误,提示fhirData.identifier可能为undefined。在不允许修改interface A的前提下,有哪些可行方案来断言对象已定义或修复该报错?
可行解决方案
1. 可选链+空值合并运算符
通过?.安全访问嵌套属性,再用??提供符合接口类型的默认值,确保返回值始终满足interface A的要求:
public static convert(fhirData: Data) { return { patientId: fhirData.identifier?.[0]?.value ?? '', firstName: fhirData.name?.[0]?.given?.[0] ?? '', initials: fhirData.name?.[0]?.given?.slice(1) ?? [], lastName: fhirData.name?.[0]?.family ?? '', }; }
这种方式兼顾类型安全和运行时容错,适合数据可能存在缺失但需要返回合法默认值的场景。
2. 自定义类型守卫做校验
如果业务上要求输入数据必须包含必要字段,可以编写类型守卫做运行时检查,同时让TypeScript编译器确认字段非空:
// 自定义类型守卫,校验必要字段是否存在 function isValidFhirData(data: Data): data is Required<Data> { return !!data.identifier?.length && !!data.name?.length && !!data.name[0].given?.length; } public static convert(fhirData: Data) { if (!isValidFhirData(fhirData)) { throw new Error('输入数据格式不合法,无法完成转换'); } return { patientId: fhirData.identifier[0].value, firstName: fhirData.name[0].given[0], initials: fhirData.name[0].given.slice(1), lastName: fhirData.name[0].family, }; }
通过类型守卫,编译器会在校验通过后认定相关字段非空,同时运行时校验也能避免空值访问导致的崩溃。
3. 非空断言运算符
若能100%确定输入数据的必要字段不会为undefined,可以直接用!断言非空,快速消除ESLint报错:
public static convert(fhirData: Data) { return { patientId: fhirData.identifier![0].value, firstName: fhirData.name![0].given![0], initials: fhirData.name![0].given!.slice(1), lastName: fhirData.name![0].family!, }; }
注意:该方式无运行时校验,若实际数据为空会触发错误,仅适用于数据来源绝对可靠的场景。
4. 解构赋值+默认值
逐层解构并设置默认值,提前处理可能的空值,让代码逻辑更清晰:
public static convert(fhirData: Data) { const { identifier = [], name = [] } = fhirData; const [firstIdentifier = {}] = identifier; const [nameEntry = { given: [], family: '' }] = name; const [firstGiven = '', ...restGiven] = nameEntry.given; return { patientId: firstIdentifier.value ?? '', firstName: firstGiven, initials: restGiven, lastName: nameEntry.family, }; }
通过解构时的默认值设置,确保每一步访问的属性都不会是undefined,同时返回值完全符合interface A的类型要求。
内容的提问来源于stack exchange,提问作者icarus
相关产品推荐
相关产品推荐

