我有以下功能,它的工作原理就像一个魅力:
type BuildInfo = {
git: {
branch: string
commitId: string
shortCommitId: string
commitTime: string | number
}
build: {
name: string
version: string
time: string | number
}
}
const getRemoteRevision = async () => {
try {
const response = await fetch('/meta.json')
const version: BuildInfo = await response.json()
return version?.git.commitId
} catch {}
}
我使用的是xojs,它将@typescript-eslint/no-unsafe-assignment
eslint规则定义为 error 级别。
在这段代码中,tsc
很好,不会抱怨任何错误……IDE内省显示以下类型:
getRemoteRevision
:() => Promise<string | undefined>
response
:Response
version
:BuildInfo
Body.json()
:Promise<any>
所以,正如你可以通过代码,eslint规则和类型猜到的... ESLint不满意,并在定义version
变量的行上出现@typescript-eslint/no-unsafe-assignment
错误。
我找不到任何方法让错误消失!我尝试了很多方法,但都失败了:
const response: Response & { json: () => Promise<BuildInfo> } = await fetch('/meta.json')
const version: BuildInfo = await response.json()
// ---
const version: BuildInfo = await response.json<Promise<BuildInfo>>()
// ---
const version = (await response.json()) as unknown as BuildInfo
我是TypeScript的新手,我真的不明白这段代码到底错在哪里?或者是ESLint规则被打破了?还是限制太多?
同样奇怪的是,tsc
可以使用这段代码(在严格模式下运行),而ESLint却不行?
1条答案
按热度按时间8i9zcol21#
规则在这里报告,因为您将
any
分配给一个类型不是any
的变量。显式注解并没有改变这样一个事实,即这里存在一个固有的不安全赋值!您的代码是在假设您的端点将始终匹配
BuildInfo
的形状的基础上工作的-但是考虑到它是一个外部API调用,有很多方法可能会失败并返回一个不匹配形状的对象。如果你对代码库中的这种不安全性没有意见,那么你可以使用以下解决方案之一:
至于如果你想安全的话,你可以做些什么--简而言之,你想验证结果是一个与预期类型匹配的对象。有像zod这样的库可以让你很容易地执行这样的验证,或者你可以手工制作你自己的。