TypeScript联合类型访问属性报错:假值判断为何不被认可?
解决TypeScript联合类型访问独有属性的报错
你遇到的错误是因为TypeScript对联合类型的类型检查逻辑:你的ServerResponse是两个对象类型的联合,它们只有token是共有的属性,error和result分别属于各自的分支。TypeScript在没有明确类型守卫的情况下,无法确定当前res到底是哪个分支,所以直接访问error(或result)会触发报错——它不会默认推断“有result就不存在error”这个业务规则。
下面是两种可行的解决方式:
方法1:用in操作符做类型守卫
通过检查属性是否存在,让TypeScript自动缩小当前变量的类型范围:
type ServerResponse = { token: string; result: any } | { token: string; error: any }; function handleNotificationsResponse(res: ServerResponse) { if ('error' in res) { // 此时TS明确知道res是带error的分支 console.error('处理错误:', res.error); } else { // 此时TS明确知道res是带result的分支 console.log('处理结果:', res.result); } }
方法2:使用判别式联合(更规范)
给联合类型的每个分支添加一个唯一的判别字段(比如type),这是TypeScript官方推荐的联合类型最佳实践,能让类型判断更清晰:
// 拆分分支并添加判别字段 type SuccessResp = { type: 'success'; token: string; result: any }; type ErrorResp = { type: 'error'; token: string; error: any }; type ServerResponse = SuccessResp | ErrorResp; function handleNotificationsResponse(res: ServerResponse) { switch (res.type) { case 'success': console.log('成功:', res.result); break; case 'error': console.error('失败:', res.error); break; } }
补充说明
你觉得“有result时res.error应为假值”是从业务逻辑出发的,但TypeScript的类型系统是结构型的,它不会自动关联这种隐含的业务规则。必须通过类型守卫或判别式,明确告诉TS如何区分联合类型的不同分支,才能安全访问独有属性。
内容的提问来源于stack exchange,提问作者Simon H
相关产品推荐
相关产品推荐

