如何完成这个 TS 函数的声明?-灵析社区

光光哥乌昂

我想封装一个通用的 `get` 函数: enum Api { allPage = 'https://api.example.com/allPage', page = 'https://api.example.com/page/:id', comment = 'https://api.example.com/page/:id/comment' } type PageComment = { content: string } type Page = { content: string } type TMap = { [K in Api]: { [Api.allPage]: { param: never query: { limit: number } data: Page[] }, [Api.page]: { param: { id: number } query: never data: Page }, [Api.comment]: { param: { id: number } query: { limit: number } data: PageComment } }[K] } 其中 `param` 是必选的 url 参数,`query` 是可选的查询参数,`data` 指定 api 的返回类型,我希望能够这样使用 `get` 函数: // https://api.example.com/allPage // 返回 Page[] get(Api.allPage) // https://api.example.com/page/12345/comment // 返回 PageComment get(Api.comment, { param: { id: 12345 } }) // https://api.example.com/page/12345/comment?limit=20 get(Api.comment, { param: { id: 12345 }, query: { limit: 20 } }) // 错误:url 参数 id 为指定 // 返回 never get(Api.comment) 这是我现在写的: function get( api: T, { param, query }: { param?: TMap[T]["param"], query?: TMap[T]['query'] } = {} ): TMap[T]["data"] { // TODO throw 'Unimplented' } 现在可以在 `param` 为 `never` 时省略第二个参数,但是 `param` 不是 `never` 时省略第二个参数没有错误提示。我应该如何改进我的代码?

阅读量:12

点赞量:0

问AI
拿走不谢 type Opts = TMap[T]['param'] extends never ? [opts?: { query?: TMap[T]['query'] }] : [opts: { param: TMap[T]['param']; query?: TMap[T]['query'] }] function get(api: T, ...args: Opts): TMap[T]['data'] { // TODO throw 'Unimplented' } 也可以使用函数重载,一个对外强制类型,一个对内稍微宽松一些 function get(api: T, ...args: Opts): TMap[T]['data']; function get(api: Api, opts: {param?: object, query?: object} = {}): any { // TODO throw 'Unimplented' }