TypeScript联合类型入参访问属性报不存在错误如何解决?
TypeScript联合类型属性访问报错解决方案
问题根源
你遇到的报错是TypeScript联合类型的常规限制:对于Combination = ResponseType1 | ResponseType2这类联合类型,默认状态下只允许访问所有成员共有的属性,也就是两个接口都存在的thirdAttr。你尝试直接访问仅单个接口拥有的firstAttr、secondAttr时,类型系统无法确定当前response所属的具体类型,因此抛出属性不存在的错误。
可行解决方案
以下方案均兼容TS3.0.1版本,且不需要修改原有接口定义、无需将字段设为可选:
方案1:使用类型守卫收窄类型(最推荐,无运行时风险)
通过自定义类型谓词明确判断当前response的具体类型,TypeScript会自动识别类型守卫的判断逻辑,自动收窄对应作用域内的变量类型:
// 自定义类型守卫 function isResponseType1(response: Combination): response is ResponseType1 { return 'firstAttr' in response } function functionA(response: Combination) { if (isResponseType1(response)) { return { first: response.firstAttr, third: response.thirdAttr } } else { return { second: response.secondAttr, third: response.thirdAttr } } }
如果要保留原有的短路判断写法,也可以在访问属性前先做类型收窄:
function functionA(response: Combination) { const isType1 = isResponseType1(response) return { ...(someCondition() && isType1) && { first: response.firstAttr }, ...(!someCondition() && !isType1) && { second: response.secondAttr }, third: response.thirdAttr } }
方案2:使用类型断言(适合100%确定业务逻辑中类型匹配的场景)
如果你的业务逻辑可以保证someCondition()为true时,response一定是ResponseType1、someCondition()为false时,response一定是ResponseType2,可以直接用类型断言跳过静态检查:
function functionA(response: Combination) { return { ...(someCondition()) && { first: (response as ResponseType1).firstAttr }, ...(!someCondition()) && { second: (response as ResponseType2).secondAttr }, third: response.thirdAttr } }
注意:该方案属于强制绕过类型检查,如果实际运行时类型和你的预期不符,会出现运行时报错。
方案3:直接用in操作符内联收窄类型
无需单独封装类型守卫,直接在作用域内用in操作符判断属性存在性,TS3.0+支持自动收窄类型:
function functionA(response: Combination) { const hasFirstAttr = 'firstAttr' in response return { ...(someCondition() && hasFirstAttr) && { first: response.firstAttr }, ...(!someCondition() && !hasFirstAttr) && { second: response.secondAttr }, third: response.thirdAttr } }
内容的提问来源于stack exchange,提问作者DEEPESH KUMAR R
相关产品推荐
相关产品推荐

