TypeScript泛型子类型判断:解决类型赋值错误问题
问题分析与解决
错误原因
你遇到的TypeScript错误核心在于泛型T的约束范围和实际赋值的类型不匹配。
T extends ResponseBody意味着T可以是ResponseBody联合类型中的任意一个子类型(比如某个具体的接口),但你的代码逻辑是根据Content-Type动态返回JSON对象或字符串。当T被实例化为某个具体接口类型时,字符串类型自然无法赋值给它——TypeScript静态检查无法提前知道运行时会返回哪种类型,所以会抛出类型不兼容的错误。
解决方案
方案1:移除泛型,直接使用ResponseBody类型
既然你的逻辑就是返回ResponseBody联合类型中的一种,完全不需要泛型来约束。直接将responseBody的类型声明为ResponseBody即可:
const response = await fetch(url, config); const contentType = response.headers.get("Content-Type"); let responseBody: ResponseBody; if (contentType && contentType.includes("application/json")) { responseBody = await response.json(); } else { responseBody = await response.text(); }
方案2:保留泛型,使用类型断言(谨慎使用)
如果业务场景必须保留泛型,可以用类型断言告诉TypeScript你确认当前赋值的类型符合T的约束。但要注意:这会跳过TypeScript的静态检查,如果实际返回的类型和T不匹配,运行时会出现错误。
const response = await fetch(url, config); const contentType = response.headers.get("Content-Type"); let responseBody: T; if (contentType && contentType.includes("application/json")) { responseBody = (await response.json()) as T; } else { responseBody = (await response.text()) as T; }
如何确定responseBody的子类型
在运行时,你可以通过类型守卫来判断responseBody具体属于哪个子类型:
- 对于字符串:直接用
typeof判断 - 对于JSON对象:可以判断类型为
object,或者检查对象是否包含特定属性(比如接口定义的字段)
示例(假设ResponseBody是{ code: number; msg: string } | string):
// 判断是否为字符串类型 if (typeof responseBody === 'string') { console.log('返回文本:', responseBody); } else { // 这里responseBody自动推断为{ code: number; msg: string }类型 console.log('返回JSON:', responseBody.code, responseBody.msg); }
内容的提问来源于stack exchange,提问作者geeshta
相关产品推荐
相关产品推荐

