如何在Angular中基于API响应用TypeScript实现条件类型切换?
问题
我正在开发一个依赖API响应的Angular组件,API会返回两种结构的数据:
- 无错误时:
Data : { Status: string; Data: number; }
- 出现错误时:
Data : { Status: string; Error: string; Message: string; }
可见Status为公共字段,我已定义如下接口:
interface ApiModel { Status: string; } interface DataModel extends ApiModel { Data: number; } interface ErrorModel extends ApiModel { ErrorCode: string; Message: string; }
我希望通过TypeScript让变量支持两种类型,并在响应中传递该类型,且不想使用可选类型。期望实现如下逻辑:
if (typeof Response === DataModel){ Response: DataModel; // 其他代码 } else { Response:ErrorModel; // 其他代码 }
我的API调用代码如下:
getReminder(reminderId: number) { const API_URL = `${this.BASE_URL}users/${this.userId}/reminders/${reminderId}`; return this.httpClient.get<ErrorModel | DataModel>(API_URL, this.options).pipe( map((data: ErrorModel | DataModel) => { return data; }) ); }
请问如何实现这种非可选的条件类型切换?
解决方案
你需要用TypeScript类型守卫来实现这种条件类型切换,因为typeof只能判断原始类型(string/number等),无法直接识别接口类型(接口是编译时概念,运行时不存在)。以下是两种可行方案:
方案1:使用in操作符进行类型收窄
直接在条件判断里检查对象是否包含目标类型的独有属性,TypeScript会自动收窄类型:
// 获取响应数据后处理示例 this.getReminder(1).subscribe(response => { if ('Data' in response) { // 此处TypeScript自动推断response为DataModel类型 console.log(response.Data); } else { // 此处自动推断为ErrorModel类型 console.log(response.ErrorCode, response.Message); } });
方案2:自定义类型守卫函数
如果需要更复杂的判断逻辑,可以写自定义函数明确告诉TypeScript类型:
// 定义类型守卫函数 function isDataModel(data: ApiModel): data is DataModel { return 'Data' in data; } function isErrorModel(data: ApiModel): data is ErrorModel { return 'ErrorCode' in data && 'Message' in data; } // 使用示例 this.getReminder(1).subscribe(response => { if (isDataModel(response)) { // response被推断为DataModel console.log(response.Data); } else { // response被推断为ErrorModel console.log(response.ErrorCode, response.Message); } });
补充说明
- 你的API调用代码已经正确指定了返回类型为
ErrorModel | DataModel,无需修改; - 不需要给接口加可选属性,通过类型守卫就能精准区分两种类型;
- 注意接口字段要和API响应保持一致:如果API错误返回的是
Error字段,记得把ErrorModel里的ErrorCode改成Error,避免判断出错。
内容的提问来源于stack exchange,提问作者SANYAM CHAURASIA
相关产品推荐
相关产品推荐

