【发布时间】:2023-01-18 01:19:36
【问题描述】:
我正在尝试编写一个函数,它将接受一个 API 字符串和一个方法,并找出它的请求和响应类型。到目前为止,这是我的尝试。
interface APIDef {
'/api/api1': {
GET: {
request: {
api1getparam1: string,
api1getparam2: number,
},
response: {
api1getres1: string[],
api1getres2: number[],
}
},
POST: {
request: {
api1postparam1: string,
api1postparam2: number,
},
response: {
api1postres1: string[],
api1postres2: number[],
}
},
},
'/api/api2': {
GET: {
request: {
api2getparam1: boolean,
api2getparam2: number,
},
response: {
api2getres1: string[],
api2getres2: number[],
}
},
POST: {
request: {
api2postparam1: boolean
},
response: {
api2postres1: 'success',
}
},
},
}
async function callAPI<A extends keyof APIDef, M extends APIDef[A]>(api: A, method: M, request: APIDef[A][M]['request']): Promise<APIDef[A][M]['response']> {
return await (await fetch(api, {
method: method,
body: JSON.stringify(request)
})).json() as ReturnType<typeof callAPI<A, M>>;
}
但是打字稿似乎无法确定 APIDef[A][M] 的类型,尽管我看不出有任何原因无法确定。这似乎是known issue。作为解决方法,我尝试了以下方法,其中 method 是固定的联合类型:
interface APIDef {
'/api/api1': {
GET: {
request: {
api1getparam1: string,
api1getparam2: number,
},
response: {
api1getres1: string[],
api1getres2: number[],
}
},
POST: {
request: {
api1postparam1: string,
api1postparam2: number,
},
response: {
api1postres1: string[],
api1postres2: number[],
}
},
PUT: never,
PATCH: never,
DELETE: never,
HEAD: never,
},
'/api/api2': {
GET: {
request: {
api2getparam1: boolean,
api2getparam2: number,
},
response: {
api2getres1: string[],
api2getres2: number[],
}
},
POST: {
request: {
api2postparam1: boolean
},
response: {
api2postres1: 'success',
}
},
PUT: never,
PATCH: never,
DELETE: never,
HEAD: never,
},
}
type Method = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD';
async function callAPI<A extends keyof APIDef, M extends Method>(api: A, method: M, request: APIDef[A][M]['request']): Promise<APIDef[A][M]['response']> {
return await (await fetch(api, {
method: method,
body: JSON.stringify(request)
})).json() as ReturnType<typeof callAPI<A, M>>;
}
这可行,但要求所有 API 都具有所有方法,即使它们未被使用也是如此。我如何重写通用代码,以便不必在所有 API 中包含所有方法就可以摆脱困境?
【问题讨论】:
标签: typescript typescript-generics