
嗯,通过 openapi-typescript 生成 swagger 的类型定义(类型定义文件内容如下)
export interface paths { "/api/cusfood/create": { post: operations["controller-cusfood-create"]; }; } export interface definitions { cusfoodRequest: { ch?: number; energy: number; fat?: number; protein?: number; }; cusfoodResponse: { /** 状态码 */ code: number; /** 具体数据 */ data: definitions["cusfoodbody"]; /** 是否成功 */ success?: boolean; }; } export interface operations { "controller-cusfood-create": { parameters: { body: { /** ( post 对应 body 请求,请求值设定为用户习惯信息 )。 */ body: definitions["cusfoodRequest"]; }; }; responses: { /** ( 响应 )。 */ 200: { schema: definitions["cusfoodResponse"]; }; }; }; } 然后我想写个方便的泛型函数,来约束入参类型,以及方便编辑器提示出参类型
const xFetch = < Path extends keyof paths, OpName extends keyof paths[Path], Query extends ???, Body extends ???, Resp extends ??? > (path: Path, opName: OpName, query: Query, body: Body): Promise<Resp> => { // 由于 path + OpName 具有唯一性 // 那么应该可以利用 typescript 里面的 可辨识联合 来推导出 Query, Body, Resp 的类型 } 求助
谢谢
1 Sparetire 2021-03-18 01:45:33 +08:00 via Android Body extends Pick<Pick<Pick<operations, keyof operations>, 'parameters'>, 'body'> 手机打字没测试。。不一定对 Resp 类似 Query type Key = string; type Value = string; type QS = '${Key}=${Value}'; Query extends QS |
2 ruandao OP @Sparetire 不大对,你这个方式 Pick 和 operations["xxx"] 能够得到一样的类型,但是这里想要的是 从 url 那边开始推导出类型,operations["xxx"] 得到的类型 无法关联到具体的类型 |
3 RaminZhong 2021-03-18 22:18:54 +08:00 不太清楚你要的是哪种效果,试着写了下 const xFetch = < Path extends keyof paths, OpName extends keyof paths[Path], Parameters extends paths[Path][OpName] extends { parameters: { query?: any; body?: any } } ? paths[Path][OpName]["parameters"] : { query: any; body: any } >( path: Path, opName: OpName, query: Parameters["query"]["query"], body: Parameters["body"]["body"] ): Promise< paths[Path][OpName] extends { responses: { [key: number]: { schema: any } } } ? paths[Path][OpName]["responses"][keyof paths[Path][OpName]["responses"]] extends { schema: any } ? paths[Path][OpName]["responses"][keyof paths[Path][OpName]["responses"]]["schema"] : any : any > => { return {} as any; }; 冗余地方有点多,你可以自行优化下 |