我正在编写一个简单的Axios Package 器函数,它结合了zod解析,并返回一个有区别的并集,以便更好地处理错误。在某些情况下,Axios的默认行为应该保留在它应该抛出任何错误的地方。我已经通过重载将{ throw: true }
传递给config
参数成功地实现了这个功能,我不喜欢的是实现的冗长。有没有办法让下面的重载更干燥?理想情况下,声明泛型Schema
和Parsed
一次,而不是重复它们三次?
import type { AxiosRequestConfig } from 'axios';
import * as z from 'zod';
import * as URLS from '~/constants/api-url-constants';
import { coerceError } from '~/utils';
type Result<T> = { ok: true; response: T } | { ok: false; error: Error };
type Url = string | ((urls: typeof URLS) => string);
interface Config<Schema extends z.Schema, Throw extends boolean>
extends AxiosRequestConfig {
schema?: Schema | ((zod: typeof z) => Schema);
throw?: Catch;
}
/**
* Axios wrapper which accepts Zod-schema to parse
* response data and return typed response inferred from schema's output type.
* Schema validations happens in `config.transformResponse`,
* meaning that failed Zod parsing is able to be intercepted.
*
* Returns discriminated union by default for error handling.
* Use overload `config.catch` to throw unsuccessful api-call like native axios.
*/
async function axiosWrapper<
Schema extends z.Schema = z.ZodUnknown,
Parsed = z.output<Schema>,
>(url: Url, config: Config<Schema, false>): Promise<Result<Parsed>>;
async function axiosWrapper<
Schema extends z.Schema = z.ZodUnknown,
Parsed = z.output<Schema>,
>(url: Url, config: Config<Schema, true>): Promise<Parsed>;
async function axiosWrapper<
Schema extends z.Schema = z.ZodUnknown,
Parsed = z.output<Schema>,
>(url: Url, config: Config<Schema, boolean>): Promise<Result<Parsed> | Parsed> {
// …implmentation
}
1条答案
按热度按时间kninwzqo1#
减少你必须编写的泛型的数量是可能的,并且通常可以删除重复的代码。然而,这也会改变你使用函数的方式。
例如,以下方法可行:
在这种情况下,我们必须创建一个 Package 函数,因为它必须能够将泛型传递给实现函数。
缺点是,我们现在必须使用函数如下:
而不是能够做到:
我的建议是继续重写泛型并坚持使用函数重载的实现