如何解决@typescript-eslint/no-unsafe-assignment与fetch的类型报错问题?
问题分析与解决方案
核心问题
你的代码在TypeScript严格模式下编译通过,但ESLint(由xojs启用)抛出@typescript-eslint/no-unsafe-assignment错误,本质是TypeScript编译检查和ESLint安全规则的侧重点不同:
- TypeScript信任你提供的类型标注/断言,只要语法上符合类型兼容规则就会通过编译;
@typescript-eslint/no-unsafe-assignment规则则专门检查「将未知类型(如response.json()返回的unknown)直接赋值给明确类型变量」的风险,哪怕你加了类型标注,它依然会认为这个赋值未经过安全验证。
你尝试的方法问题点
- 强行修改
Response类型:你给response添加的自定义类型只是欺骗了TypeScript,但ESLint仍能识别response.json()的本质是返回unknown,因此报错; - 泛型参数错误:
response.json<Promise<BuildInfo>>()的写法有误,json()的泛型参数应该是返回值的具体类型(BuildInfo),而非Promise<BuildInfo>——因为json()本身就返回Promise<T>; - 类型断言写法:
as unknown as BuildInfo是可行的,但可能你的ESLint规则配置对这种断言有额外限制,或者需要结合规则注释使用。
正确解决方案
方案1:正确使用json()的泛型
fetch的Response.json()支持传入泛型参数,直接指定返回值类型,这是最规范的写法,能同时满足TS编译和ESLint规则:
const getRemoteRevision = async () => { try { const response = await fetch('/meta.json'); // 正确传入泛型参数BuildInfo,让json()返回Promise<BuildInfo> const version: BuildInfo = await response.json<BuildInfo>(); return version?.git.commitId; } catch {} };
方案2:使用类型断言并兼容ESLint
如果泛型方式仍报错,可通过双重类型断言明确告诉ESLint你确认数据类型安全,或者临时禁用该行规则:
// 方式A:双重类型断言 const getRemoteRevision = async () => { try { const response = await fetch('/meta.json'); const version = (await response.json()) as unknown as BuildInfo; return version?.git.commitId; } catch {} }; // 方式B:临时禁用ESLint规则(仅当你确认数据绝对安全时使用) const getRemoteRevision = async () => { try { const response = await fetch('/meta.json'); // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const version: BuildInfo = await response.json(); return version?.git.commitId; } catch {} };
为什么TS编译通过但ESLint报错?
TypeScript的类型检查是编译时静态检查,它信任你提供的类型标注和断言,不会验证运行时数据是否真的符合类型定义;而@typescript-eslint/no-unsafe-assignment规则是ESLint提供的额外安全校验,目的是提醒你:外部数据(如接口返回的JSON)可能不符合你定义的类型,直接赋值存在运行时风险。
内容的提问来源于stack exchange,提问作者Nicolas Goudry
相关产品推荐
相关产品推荐

