如何使用 ...rest ...spread 正确键入函数包装器以获取重载?
Posted
技术标签:
【中文标题】如何使用 ...rest ...spread 正确键入函数包装器以获取重载?【英文标题】:How to correctly type a function wrapper using ...rest ...spread to pick up overloads? 【发布时间】:2020-04-21 01:35:33 【问题描述】:我正在尝试为Axios npm package 中的axios
函数制作一个包装器。
这个函数可以被调用
axios(config: AxiosRequestConfig)
// When URL is contained inside config
或
axios(
url: string,
config: AxiosRequestConfig,
)
// when it's not
我的简单包装器如下所示:
import axios from 'axios'
type AxiosArguments = Parameters<typeof axios>
const axiosWrapper = async (...args: AxiosArguments) => await axios(...args)
export default axiosWrapper
但是,TypeScript 不会以这种方式承受过载 - 当我尝试时
export const fetchSomething = () => wrappedAxios(
url: '/url/to/something/',
method: 'get',
)
我收到一个错误:
错误:(5, 60) TS2345: 类型参数 ' url: string; ' 不可分配给“字符串”类型的参数。
如何让它发挥作用?我宁愿学习一般情况下这样做,而不是仅仅从 Axios 导入正确的类型。
【问题讨论】:
看看这个看看参数类型别名是如何工作的:***.com/questions/51851677/… 【参考方案1】:我可能会使用function overload:
async function axiosWrapper(config: AxiosRequestConfig): Promise<AxiosReturnValue>;
async function axiosWrapper(url: string, config: AxiosRequestConfig): Promise<AxiosReturnValue>;
async function axiosWrapper(urlOrConfig: string|AxiosRequestConfig, config?: AxiosRequestConfig): Promise<AxiosReturnValue>
if (typeof urlOrConfig === "string")
// The version with a URL
return /*...*/;
// The version without
return /*...*/;
AxiosReturnValue
是上面的占位符。您希望它是您从包装器返回的任何内容。如果您要返回 axios
返回的内容,请使用它使用的相同返回类型。 (如果是Promise
类型,请直接使用它,而不是在Promise
中。例如,如果axios
的返回类型是Promise<Something>
,则使用Promise<Something>
,而不是Promise<Promise<Something>>
。)
它looks like axios 使用通用返回类型AxiosResponse<T>
。如果是,那么:
async function axiosWrapper<T>(config: AxiosRequestConfig): Promise<AxiosResponse<T>>;
async function axiosWrapper<T>(url: string, config: AxiosRequestConfig): Promise<AxiosResponse<T>>;
async function axiosWrapper<T>(urlOrConfig: string|AxiosRequestConfig, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>
if (typeof urlOrConfig === "string")
// The version with a URL
return /*...*/;
// The version without
return /*...*/;
【讨论】:
我试过这个,通过type AxiosReturnValue = ReturnType<typeof axios>
获取 AxiosReturnValue,但我得到 Error:(9, 3) TS2739: Type AxiosResponse' is missing the following properties from type 'AxiosPromise': then, catch, [Symbol.toStringTag], finally-.
当我执行 type AxiosReturnValue = Axios.AxiosPromise
时,我得到 Error:(4, 58) TS1055: Type 'AxiosPromise' is not a valid async function return type in ES5/ES3 因为它没有引用到一个与 Promise 兼容的构造函数值。
@MichalKurz - 我已经更新了答案,我应该提到 AxiosReturnType
是一个占位符。请参阅有关返回类型的新段落以及有关AxiosResponse<T>
的以下内容。以上是关于如何使用 ...rest ...spread 正确键入函数包装器以获取重载?的主要内容,如果未能解决你的问题,请参考以下文章
ES6数组扩展运算符(Rest+Spread)类方法原型方法