TypeScript使用fetch做数据转换时res.body.message不存在报错如何解决
问题原因
你定义的泛型T没有任何类型约束,TS无法确认T类型上存在message属性,因此抛出类型错误。
解决方案
方法1:给泛型增加基础约束(推荐)
先定义所有接口返回体通用的基础类型,再让泛型T继承该类型:
// 通用接口返回基础类型,所有业务返回体都符合该结构 interface BaseApiResponse { message?: string } // 泛型增加继承约束 function api<T extends BaseApiResponse>(url: string): Promise<T> { return fetch(url) .then((res) => { return res.json().then((resJson: T) => ({ ok: res.ok, status: res.status, body: resJson, })); }) .then((res) => { if (res.ok) { return res.body; } return Promise.reject({ status: res.status, message: res.body.message, }); }); }
你的业务返回类型ResBody本身已经包含可选message属性,因此调用时无需修改原有代码,即可正常使用。
方法2:临时类型断言(仅适合临时修复)
如果不想修改泛型定义,可以在访问message时手动增加类型断言:
return Promise.reject({ status: res.status, message: (res.body as { message?: string }).message, });
额外优化:catch 错误类型安全
TS中catch回调的参数默认是unknown类型,你可以增加类型收窄逻辑保证访问err.message和err.status时不会报错:
type ApiError = { status: number message?: string } type ResBody = { success: boolean; message?: string; data?: string[]; }; api<ResBody>("https://example.com") .then(({ success, data }) => { console.log(success, data); }) .catch((err: unknown) => { // 类型收窄判断 const isApiError = (val: unknown): val is ApiError => { return !!val && typeof val === 'object' && 'status' in val } if (isApiError(err)) { console.log(err.message, err.status) } });
内容的提问来源于stack exchange,提问作者apl-by
相关产品推荐
相关产品推荐

