如何投一个Promise<Response>?

How to cast a Promise<Response>?

我使用 fetch 从 API.

查询一些 JSON 数据

我写的辅助函数returns一个Promise<Response>(这是简化版)

const apiCall = (): Promise<Response> => fetch('http://the.api.com').then(r => r.json())

然后我这样使用它:

export class Case {
  Uuid?:       string
  Topic?:      string
  public constructor(init?:Partial<Case>) {
    Object.assign(this, init);
  }
}

callApi()
  .then(r => allCases.value = r.Data as Array<Case>) // the error is on this line
  .catch(() => {{}})

我的问题: TypeScript 报错:

TS2339: Property 'Data' does not exist on type 'Response'.

程序无论如何都成功通过,但我想了解这个错误并修复它(主要是为了更好地理解 TS)。

然后我尝试用预期的类型提示 r

interface ApiResponse {
  Data: Array<Case>
}

callApi('/case', 'GET')
  .then((r: ApiResponse) => allCases.value = r.Data as Array<Case>)
  .catch(() => {{}})

这会导致两个错误:

TS2345: Argument of type '(r: ApiResponse) =&gt; Case[]' is not assignable to parameter of type '(value: Response) =&gt; Case[] | PromiseLike&lt;Case[]&gt;'.
Types of parameters 'r' and 'value' are incompatible.
Property 'Data' is missing in type 'Response' but required in type 'ApiResponse'.

ESLint: This assertion is unnecessary since it does not change the type of the expression. (@typescript-eslint/no-unnecessary-type-assertion)

我如何表达这样一个事实,即来自我的辅助函数的内容应该被视为一个对象(使用 Data 键)

您可以定义callApi如下:

const callApi = (): Promise<ApiResponse> => fetch('http://the.api.com').then(r => r.json())

看着 type definitions of node-fetch 告诉我:

  • Return fetch 的类型是 Promise<Response>
  • Return Response.json 的类型是 Promise<unknown>

因此 callApi 函数的 return 类型是 Promise<unknown> 而不是 Promise<Response>

那么这应该可行:

callApi().then(r => allCases.value = r.Data).catch(() => {{}})

为什么你的这个解决方案不起作用:

callApi('/case', 'GET')
    .then((r: ApiResponse) => allCases.value = r.Data as Array<Case>)
    .catch(() => {{}})

这里你将一个 wrongly-types 回调函数作为参数传递给 then 因为 r 的类型不是 ApiResponse 而是 Response以前打过。这会导致 TS 错误。