typescript 类型推导, 如何提取嵌入很深的类型(场景: swagger 生成接口类型后,怎么快速的提取需要的参数类型)

2021-03-17 20:36:17 +08:00
 ruandao

嗯,通过 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 的类型
}

求助

谢谢

848 次点击
所在节点    问与答
4 条回复
Sparetire
2021-03-18 01:45:33 +08:00
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
ruandao
2021-03-18 19:40:58 +08:00
@Sparetire 不大对,你这个方式 Pick 和 operations["xxx"] 能够得到一样的类型,但是这里想要的是 从 url 那边开始推导出类型,operations["xxx"] 得到的类型 无法关联到具体的类型
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;
};


冗余地方有点多,你可以自行优化下
Sparetire
2021-03-19 14:45:57 +08:00
@ruandao 哦哦,不好意思理解错题意了,晚上脑子不太清醒。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/762597

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX