TypeScript不识别带formatter的泛型请求函数返回类型如何解决
核心原因
你当前实现的client函数没有对入参与返回值的类型做条件绑定,TypeScript会默认把所有分支的返回值合并为联合类型Promise<AxiosResponse<D> | F>,即便你调用时明确传入了formatter参数,TS也无法识别出这种场景下返回值一定是formatter的输出类型,所以才会报属性不存在的错误。
解决方案
使用函数重载为两种入参场景分别定义返回类型即可,修改后的完整代码如下:
import axios from "axios"; import { Required } from "utility-types"; import { AxiosRequestConfig, AxiosResponse } from "axios"; // 重载规则1:未传入formatter时,返回axios原始响应对象 async function client<D>( config: Required<AxiosRequestConfig, "url"> ): Promise<AxiosResponse<D>>; // 重载规则2:传入formatter时,返回formatter处理后的结果类型 async function client<D, F>( config: Required<AxiosRequestConfig, "url">, formatter: (data: D) => F ): Promise<F>; // 函数具体实现 async function client<D, F>( { url, ...config }: Required<AxiosRequestConfig, "url">, formatter?: (data: D) => F ) { const response = await axios.request<D>({ url: encodeURI(url), ...config, }); if (typeof formatter === "undefined") { return response; } return formatter(response.data); };
修改完成后调用client时,TypeScript会根据你是否传入formatter自动匹配对应的重载规则,自动推导返回值类型:
- 传
formatter时,返回值类型就是formatter的返回类型,不需要你额外手动声明接口,访问formatted.products不会再报错 - 不传
formatter时,返回值类型就是标准的AxiosResponse类型,符合原始逻辑
内容的提问来源于stack exchange,提问作者M.A Shahbazi
相关产品推荐
相关产品推荐

