如何使用 TypeScript 和 React 从 API 响应初始化接口



我正在尝试在 React + TypeScript 视图组件上呈现 API 响应。以下是用于表示 API 响应(在本例中为股票(和 API 错误的接口:

export interface IStocks {
    [key: string]: string;
}
export interface IErrors {
    [key: string]: string;
}

这是一个从某些 API 获取股票的函数,我需要帮助的编译时错误:

private async getStocks(): Promise<IStocks> {
    /*
      Generic type 'Promise<T>' requires 1 type argument(s).ts(2314)
      Ok, but how do I make this function know about IErrors and IStocks types? What is the correct way?
       */

    try {
        let response = await fetch('http://localhost:8080/api/v1/stocks', {
            method: "get",
            headers: new Headers({
                "Content-Type": "application/json",
                Accept: "application/json"
            })
        });
        return (IStocks) response;
        /*
         'IStocks' only refers to a type, but is being used as a value here.ts(2693)

         I wanted to map the response to 'IStocks' interface simply, my way is incorrect but then how do I do it
         */
    } catch (ex) {
        return (IErrors) ex;
        /*
        'IErrors' only refers to a type, but is being used as a value here.ts(2693)
         I wanted to map the response to 'IErrors' interface simply, my way is incorrect but then how do I do it
        */
    }
    return null;
}

基本上,我想将 API 错误对象ex映射到 IErrors 接口进行类型检查,将 API 响应对象映射到IStocks接口。

正确的方法是什么?

对于这样的功能,我会推荐像 axios 这样的库。

如果出于某种原因你不能使用这样的库,我会为 fetch 方法制作一个通用包装器:

export const typedFetch = <T>(
  request: RequestInfo,
  requestInit?: RequestInit
): Promise<T> => {
  return new Promise(resolve => {
    fetch(request, requestInit)
      .then(response => response.json())
      .then(body => {
        resolve(body);
      });
  });
};
// Usage:
const data = await typedFetch<IStocks[]>(
  "http://localhost:8080/api/v1/stocks",
  {
    method: "get",
    headers: new Headers({
      "Content-Type": "application/json",
      Accept: "application/json"
    })
  }
);

您可能还应该更改 API 处理错误的方式,您的 API 响应不能有两个单独的模型。

您应该在包含数据以及其他信息(如潜在错误、消息、状态代码等(的包装响应中返回所有数据。

API 返回的 JSON 可能如下所示:

{
    "status": 200,
    "errors": [],
    "data": [
        /* Stocks */
    ]
}
{
    "status": 500,
    "errors": [
        /* ERRORS */
    ],
    "data": []
}

然后,您将使用客户端的泛型模型反序列化数据:

interface IApiResponse<T> {
    status: number;
    errors: IErrors[];
    data: T;
}
const data = await typedFetch<IApiResponse<IStocks[]>>("url", ...);

好的,但是我如何让这个函数了解 IErrors 和 IStocks 类型?正确的方法是什么?

承诺只有一个泛型类型:成功响应的类型。如果您有错误,其类型为 any ,由您知道错误的实际内容。

return (IStocks) response;

那是Java,不是TypeScript。在 TypeScript 中,语法是

return response as IStocks;

但请注意,fetch 返回一个Promise<Response> 。响应包含的比响应正文更多。阅读文档和/或使用 IDE 查看响应中存在哪些属性和方法,以及如何从响应中正确提取 JSON 正文。

最新更新