@typescript-eslint/no-unsafe-assignment和浏览器获取

rjzwgtxy  于 2023-05-19  发布在  TypeScript
关注(0)|答案(1)|浏览(189)

我有以下功能,它的工作原理就像一个魅力:

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>
  • responseResponse
  • versionBuildInfo
  • 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却不行?

8i9zcol2

8i9zcol21#

规则在这里报告,因为您将any分配给一个类型不是any的变量。显式注解并没有改变这样一个事实,即这里存在一个固有的不安全赋值!
您的代码是在假设您的端点将始终匹配BuildInfo的形状的基础上工作的-但是考虑到它是一个外部API调用,有很多方法可能会失败并返回一个不匹配形状的对象。
如果你对代码库中的这种不安全性没有意见,那么你可以使用以下解决方案之一:

// 1) Use a disable comment to suppress the error:

// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- we're assuming the backend returns the correct shape
const version: BuildInfo = await response.json();
// 2) Use an assertion to change from `any` to the desired type:

const version = (await response.json()) as BuildInfo;

至于如果你想安全的话,你可以做些什么--简而言之,你想验证结果是一个与预期类型匹配的对象。有像zod这样的库可以让你很容易地执行这样的验证,或者你可以手工制作你自己的。

相关问题