TypeScript如何基于message属性值校验对象属性存在性?
解决方案
要实现你需要的类型约束,让TypeScript能通过message字段的判断正确窄化类型,联合类型是最直接的方案,或者也可以用条件类型来定义动态类型分支。
方法一:明确的联合类型定义
直接拆分出两种互斥的类型分支,再合并为联合类型,这样TypeScript可以通过message的值精准判断当前对象的属性:
// 定义OK状态的响应类型 type OkResponse = { message: 'OK'; prop1: string; prop2: number; }; // 定义ERROR状态的响应类型 type ErrorResponse = { message: 'ERROR'; error: string; }; // 合并为最终的响应类型 type SomeAnotherResponse = OkResponse | ErrorResponse;
使用示例
此时你的代码可以正常访问属性,不会出现TS错误:
const result: SomeAnotherResponse = /* 你的响应数据 */; if (result.message === 'OK') { // TS能识别当前是OkResponse类型,prop1/prop2必存在 console.log(result.prop1); } else { // TS能识别当前是ErrorResponse类型,error必存在 console.log(result.error); }
你之前用交叉类型的问题在于:交叉会把所有属性强制合并,导致prop1/prop2在ERROR状态下也被要求存在,同时error始终是可选的,完全不符合你“状态互斥”的需求,自然无法通过message判断来窄化类型。
方法二:条件类型实现动态分支
如果你希望用条件类型来定义,可以基于message的字面量类型做分支判断:
type SomeAnotherResponse<T extends 'OK' | 'ERROR'> = T extends 'OK' ? { message: T; prop1: string; prop2: number } : { message: T; error: string };
使用示例
这种方式适合需要明确指定状态类型的场景:
// 明确指定OK状态的响应 const okResult: SomeAnotherResponse<'OK'> = { message: 'OK', prop1: 'hello', prop2: 456 }; // 明确指定ERROR状态的响应 const errorResult: SomeAnotherResponse<'ERROR'> = { message: 'ERROR', error: '请求失败' };
如果是不确定状态的场景(比如接口返回可能是OK或ERROR),还是推荐用第一种联合类型的方案,因为它能让TypeScript自动进行类型窄化,无需手动指定泛型参数。
内容的提问来源于stack exchange,提问作者Dmo
相关产品推荐
相关产品推荐

