如何键入正常的fetch()返回值

huangapple go评论92阅读模式
英文:

How to type normal fetch() return value

问题

我收到的错误信息是:

> Unsafe assignment of an any value.eslint@typescript-eslint/no-unsafe-assignment

有关如何修复这个问题的建议?

英文:
type Activity = {
  activity: string
  type: string
  participants: number
  price: number
  link: string
  key: string
  accessibility: number
}

async function fetchOne(): Promise<Activity> {
  const url = "https://www.boredapi.com/api/activity"
  const res: Activity = await fetch(url).then(res => (res.json()))
  // Unsafe assignment of an `any` value.eslint@typescript-eslint/no-unsafe-assignment
  // how to fix this? 
  return res
}

I got :

> Unsafe assignment of an any value.eslint@typescript-eslint/no-unsafe-assignment

Any suggestion on how to fix this?

答案1

得分: 1

"Any suggestion on how to fix this?"

你有什么建议来修复这个问题?

"You can't."

你不能。

"The return type of an operation over the wire is fundamentally, logically unknowable at compile-time. You can't statically analyze something like that. The proper return type of response.json() should really be unknown."

在编译时,通过网络操作的返回类型在本质上和逻辑上都是不可知的。你无法在静态分析中做出这样的判断。response.json() 的正确返回类型应该是 unknown

"All you can do with dynamic data is add runtime checks to ensure that it conforms to the schema you want and move the data into type-safe constructs:"

对于动态数据,你唯一能做的就是添加运行时检查,以确保其符合你想要的模式,并将数据移入类型安全的结构中:

type Thing = {
  a: string
  b: number
}

async function getTheThing(): Promise<Thing> {
  const resp = await fetch('someurl');
  const data: unknown = resp.json();
  if (typeof data === 'object' && data && 'a' in data && 'b' in data && typeof data.a === 'string' && typeof data.b === 'number') {
    return {
      a: data.a,
      b: data.b
    }
  }

  throw new Error('bad data!')
}

Playground

请注意,编译器接受了这个代码,没有任何不安全的强制转换。同时也要注意这个繁琐的条件逻辑。你可以将其移到一个用户自定义的类型谓词中,以使其在使用时更加方便。

英文:

> Any suggestion on how to fix this?

You can't.

The return type of an operation over the wire is fundamentally, logically unknowable at compile-time. You can't statically analyze something like that. The proper return type of response.json() should really be unknown.

All you can do with dynamic data is add runtime checks to ensure that it conforms to the schema you want and move the data into type-safe constructs:

type Thing = {
  a: string
  b: number
}

async function getTheThing(): Promise&lt;Thing&gt; {
  const resp = await fetch(&#39;someurl&#39;);
  const data: unknown = resp.json();
  if (typeof data === &#39;object&#39; &amp;&amp; data &amp;&amp; &#39;a&#39; in data &amp;&amp; &#39;b&#39; in data &amp;&amp; typeof data.a === &#39;string&#39; &amp;&amp; typeof data.b === &#39;number&#39;) {
    return {
      a: data.a,
      b: data.b
    }
  }

  throw new Error(&#39;bad data!&#39;)
}

Playground

Note the compiler accepts this without any unsafe casts. Also note the cumbersome conditional logic. You can move it into a user-defined type predicate to make it a little more ergonomical to use.

huangapple
  • 本文由 发表于 2023年7月12日 23:05:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76672023.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定