【发布时间】:2019-12-19 21:41:52
【问题描述】:
我正在使用 Typescript 编写 API 包装器,并且正在考虑使用 Fetch API 和 Promises。我想在请求方法中使用泛型,以便我可以对提供的类型进行建模,但是我对 Typescript(和承诺,就此而言)相当陌生,并且在有条件地返回 Promise<T> 或 Promise<T[]> 时找不到任何东西,因为并非所有请求都会返回一个数组。
这是我的代码的状态,到目前为止,它还没有处于完成状态,但它是可行的。
export default class ApiWrapper
{
public async request<T>(endpoint: string, method: string = 'GET', parameters: object = {}) : Promise<void|T>
{
var protocol = process.env.REACT_APP_APPLICATION_PROTOCOL || 'https'
var host = process.env.REACT_APP_APPLICATION_HOST
var port = process.env.REACT_APP_APPLICATION_PORT ? `:${process.env.REACT_APP_APPLICATION_PORT}` : ''
var path = process.env.REACT_APP_APPLICATION_PATH || '/'
if (!host)
{
// TODO:- Handle error
}
let body = JSON.stringify(parameters)
return await fetch(`${protocol}://${host}${port}${path}/${endpoint}`, {
method: method,
body: body
})
.then(response => response.json() as Promise<T>)
.then(data => {
return data
})
}
public async get<T>(endpoint: string, parameters: object = {})
{
return await this.request<T>(endpoint, 'GET', parameters)
}
public async post(endpoint: string, parameters: object)
{
return await this.request(endpoint, 'POST', parameters)
}
public async put(endpoint: string, parameters: object)
{
return await this.request(endpoint, 'PUT', parameters)
}
public async delete(endpoint: string)
{
return await this.request(endpoint, 'DELETE')
}
}
我可以尝试像这样有条件地返回:
return await fetch(`${protocol}://${host}${port}${path}/${endpoint}`, {
method: method,
body: body
})
.then(response => {
if (Array.isArray(response.json())) {
return response.json() as Promise<T[]>
} else {
return response.json() as Promise<T>
}
})
.then(data => {
return data
})
虽然T 不能分配给类型T[]。这可能非常简单,愚蠢甚至不可能,但任何指针都会受到赞赏。如果有,可以提供任何其他信息
【问题讨论】:
-
@MoshFeu 哦,有趣;我什至不知道 TS 有过载!调用
request()时如何区分方法签名?鉴于我提前知道它是从端点返回的数组还是实例。 -
如果我理解这个问题,你在声明变量时声明类型。
const arr: Array = request(... -
我的意思是,如果我要重载
request方法,参数将是相同的,并且声明public async request<T[]>(endpoint: string, method: string = 'GET', parameters: object = {})将无效,因此编译器会抱怨我使用相同的方法签名(函数声明两次)。所以我正在寻找一种方法,既可以说let users: User[] = await this.request<User>('users', 'GET'),又可以说let user: User = await this.request<User>('users/12', 'GET'),并且能够处理数组和单个实例
标签: typescript fetch-api