我正在尝试在 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 正文。