You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否简化含泛型的重载函数签名,使其符合DRY原则?

优化Axios Zod包装函数的重载冗余问题

首先修正原代码里的笔误:Config接口中的throw?: Catch应该改为throw?: Throw,否则类型会不匹配。

针对你想要减少泛型重复声明的需求,可以通过条件类型+单一泛型签名来优化,只需要声明一次泛型参数,就能覆盖两种返回逻辑:

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?: Throw; // 修正原笔误:Catch → Throw
}

/**
 * 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 `config.throw: true` to throw unsuccessful api-call like native axios.
 */
async function axiosWrapper<
  Schema extends z.Schema = z.ZodUnknown,
  Parsed = z.output<Schema>,
  Throw extends boolean = false // 新增默认值为false,对应默认返回Result的行为
>(
  url: Url,
  config: Config<Schema, Throw>
): Promise<Throw extends true ? Parsed : Result<Parsed>> {
  // …实现逻辑保持不变,内部可通过config.throw的值分支处理:
  // 比如 if (config.throw) { 抛出错误 } else { 返回Result联合类型 }
}

优化关键点:

  • 只在函数顶层声明一次泛型参数Schema、Parsed和Throw,避免重复冗余。
  • 利用TypeScript的条件类型Throw extends true ? Parsed : Result<Parsed>自动推导返回值类型:
    • 当传入{ throw: true }时,返回Promise<Parsed>(和原生Axios行为一致);
    • 默认或传入{ throw: false }时,返回Promise<Result<Parsed>>(判别式联合类型)。
  • 给Throw设置默认值false,保留原函数默认返回错误联合类型的行为。

这样既保留了原有的类型安全和两种错误处理模式,又大幅简化了函数签名的冗余度。

内容的提问来源于stack exchange,提问作者Audun Olsen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 12:17:39