typescript 有没有可能用泛型的签名来清空重载函数?

3bygqnnd  于 2023-03-13  发布在  TypeScript
关注(0)|答案(1)|浏览(173)

我正在编写一个简单的Axios Package 器函数,它结合了zod解析,并返回一个有区别的并集,以便更好地处理错误。在某些情况下,Axios的默认行为应该保留在它应该抛出任何错误的地方。我已经通过重载将{ throw: true }传递给config参数成功地实现了这个功能,我不喜欢的是实现的冗长。有没有办法让下面的重载更干燥?理想情况下,声明泛型SchemaParsed一次,而不是重复它们三次?

  1. import type { AxiosRequestConfig } from 'axios';
  2. import * as z from 'zod';
  3. import * as URLS from '~/constants/api-url-constants';
  4. import { coerceError } from '~/utils';
  5. type Result<T> = { ok: true; response: T } | { ok: false; error: Error };
  6. type Url = string | ((urls: typeof URLS) => string);
  7. interface Config<Schema extends z.Schema, Throw extends boolean>
  8. extends AxiosRequestConfig {
  9. schema?: Schema | ((zod: typeof z) => Schema);
  10. throw?: Catch;
  11. }
  12. /**
  13. * Axios wrapper which accepts Zod-schema to parse
  14. * response data and return typed response inferred from schema's output type.
  15. * Schema validations happens in `config.transformResponse`,
  16. * meaning that failed Zod parsing is able to be intercepted.
  17. *
  18. * Returns discriminated union by default for error handling.
  19. * Use overload `config.catch` to throw unsuccessful api-call like native axios.
  20. */
  21. async function axiosWrapper<
  22. Schema extends z.Schema = z.ZodUnknown,
  23. Parsed = z.output<Schema>,
  24. >(url: Url, config: Config<Schema, false>): Promise<Result<Parsed>>;
  25. async function axiosWrapper<
  26. Schema extends z.Schema = z.ZodUnknown,
  27. Parsed = z.output<Schema>,
  28. >(url: Url, config: Config<Schema, true>): Promise<Parsed>;
  29. async function axiosWrapper<
  30. Schema extends z.Schema = z.ZodUnknown,
  31. Parsed = z.output<Schema>,
  32. >(url: Url, config: Config<Schema, boolean>): Promise<Result<Parsed> | Parsed> {
  33. // …implmentation
  34. }
kninwzqo

kninwzqo1#

减少你必须编写的泛型的数量是可能的,并且通常可以删除重复的代码。然而,这也会改变你使用函数的方式。
例如,以下方法可行:

  1. type AxiosWrapperFunction<
  2. Schema extends z.Schema = z.ZodUnknown,
  3. Parsed = z.output<Schema>
  4. > = {
  5. (url: Url, config: Config<Schema, false>): Promise<Result<Parsed>>;
  6. (url: Url, config: Config<Schema, true>): Promise<Parsed>;
  7. };
  8. export const createAxiosWrapper = <
  9. Schema extends z.Schema = z.ZodUnknown,
  10. Parsed = z.output<Schema>
  11. >(): AxiosWrapperFunction<Schema, Parsed> => {
  12. return (url: Url, config: Config<Schema, boolean>) => {
  13. /** implementation */
  14. };
  15. }

在这种情况下,我们必须创建一个 Package 函数,因为它必须能够将泛型传递给实现函数。
缺点是,我们现在必须使用函数如下:

  1. const axiosWrapper = createAxiosWrapper</** your generics */>();
  2. axiosWrapper(/** your arguments */)

而不是能够做到:

  1. axiosWrapper</** your generics */>(/** your arguments */)

我的建议是继续重写泛型并坚持使用函数重载的实现

展开查看全部

相关问题