TypeScript中如何为API调用返回的响应标注类型?
TypeScript fetch请求类型报错修复方案
报错核心原因
问题来自3个疏漏:
- 开启TS严格模式(
noImplicitAny: true)时,fetch链式调用的回调参数未标注类型,触发隐式any报错 - 定义的
IAppointments接口存在缺陷:results: []的写法等价于results: never[],只能接收空数组,无法匹配接口实际返回的数组数据 - 之前的类型断言位置错误:如果直接在
json()调用后不做类型匹配就断言,很容易因为类型不匹配失效,且未处理HTTP错误状态时也容易出现类型和实际数据不符的问题
修复步骤
- 给
fetch第一个then的回调参数标注TS内置的Response类型,直接解决隐式any报错 - 补全
IAppointments接口的数组元素类型,不要留空数组定义 - 在调用
json()后直接做类型断言,将返回值标记为对应接口类型,同时增加HTTP状态校验——fetch仅在网络异常时会触发reject,4xx/5xx状态码不会自动抛错
修复后完整代码
// 按接口实际返回的字段定义预约单条目类型 interface IAppointmentItem { id: number | string; // 其余字段替换为接口实际返回的属性即可,比如预约时间、用户信息等 } interface IAppointments { results: IAppointmentItem[]; } export function getAppointments(): Promise<IAppointments> { return fetch('https://dewey-smart.herokuapp.com/appointments', { method: 'GET', mode: 'cors', headers : { 'Content-Type':'application/json' } }) .then((data: Response) => { if (!data.ok) { throw new Error(`请求异常,状态码:${data.status}`); } // 对json()解析后的值做类型断言 return data.json() as Promise<IAppointments>; }); }
额外优化建议
- 如果不想每次手动标注
Response类型,检查tsconfig.json配置:浏览器环境下需要在lib数组中加入"DOM",Node环境下需要安装对应版本的@types/node,配置正确后TS可以自动推导fetch回调的参数类型 - 用async/await写法可读性更高,等价实现如下:
export async function getAppointments(): Promise<IAppointments> { const resp = await fetch('https://dewey-smart.herokuapp.com/appointments', { method: 'GET', mode: 'cors', headers : { 'Content-Type':'application/json' } }); if (!resp.ok) { throw new Error(`请求异常,状态码:${resp.status}`); } return resp.json() as Promise<IAppointments>; }
内容的提问来源于stack exchange,提问作者Revolutionary Citron
相关产品推荐
相关产品推荐

