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

TypeScript函数重载问题:字符串或自定义对象参数的类型匹配

正确重载TypeScript中的badRequest函数

我尝试在TypeScript中重载badRequest函数,期望实现三种调用场景:

  • 无参调用时,返回仅包含message字段的响应
  • 传入字符串时,返回包含message和字符串类型errors的响应
  • 传入Zod格式化错误对象时,返回包含message和对应类型errors的响应

但当前代码调用时出现TypeScript类型错误。

原代码

/**
 * Returns a 400 Bad Request error.
 *
 * @returns A response with the 400 status code and a message.
 */
export function badRequest(): TypedResponse<{ message: string }>;
/**
 * Returns a 400 Bad Request error.
 *
 * @param errors - An object containing the errors from the Zod schema.
 * @returns A response with the 400 status code, a message and the errors.
 */
export function badRequest<T>(
  errors: ZodFormattedError<T>,
): TypedResponse<{ message: string; errors: ZodFormattedError<T> }>;
/**
 * Returns a 400 Bad Request error.
 *
 * @param errors - An error string.
 * @returns A response with the 400 status code, a message and the errors.
 */
export function badRequest(
  errors: string,
): TypedResponse<{ message: string; errors: string }>;
export function badRequest<T>(errors?: ZodFormattedError<T> | string) {
  return json(
    { message: 'Bad Request', ...(errors && { errors }) },
    { status: 400 },
  );
}

const myRequest = badRequest({
  _errors: [
    {
      code: 'invalid_type',
      expected: 'string',
      received: 'number',
      path: ['name'],
      message: 'Expected string, received number',
    },
  ],
});

报错信息

No overload matches this call.
  Overload 1 of 3, '(errors: ZodFormattedError<{ _errors: unknown; }, string>): TypedResponse<{ message: string; errors: ZodFormattedError<{ _errors: unknown; }, string>; }>', gave the following error.
    Type '{ code: string; expected: string; received: string; path: string[]; message: string; }' is not assignable to type 'string'.
  Overload 2 of 3, '(errors: string): TypedResponse<{ message: string; errors: string; }>', gave the following error.
    Argument of type '{ _errors: { code: string; expected: string; received: string; path: string[]; message: string; }[]; }' is not assignable to parameter of type 'string'.

问题原因

  1. 重载匹配顺序冲突:TypeScript按重载定义的顺序匹配调用,第一个带泛型的重载优先匹配传入的对象,但ZodFormattedError<T>默认第二个类型参数为string(错误消息类型),与你传入的对象类型_errors元素不兼容。
  2. 类型推断缺失:手动构造的Zod错误对象未被标记为ZodFormattedError类型,导致TypeScript无法匹配正确的重载。

修正方案

方案1:调整重载顺序并完善泛型定义

将字符串参数的重载放在泛型重载之前,同时显式声明错误消息的类型参数,提升TypeScript的推断准确性:

/**
 * Returns a 400 Bad Request error.
 *
 * @returns A response with the 400 status code and a message.
 */
export function badRequest(): TypedResponse<{ message: string }>;
/**
 * Returns a 400 Bad Request error.
 *
 * @param errors - An error string.
 * @returns A response with the 400 status code, a message and the errors.
 */
export function badRequest(
  errors: string,
): TypedResponse<{ message: string; errors: string }>;
/**
 * Returns a 400 Bad Request error.
 *
 * @param errors - An object containing the errors from the Zod schema.
 * @returns A response with the 400 status code, a message and the errors.
 */
export function badRequest<T, E>(
  errors: ZodFormattedError<T, E>,
): TypedResponse<{ message: string; errors: ZodFormattedError<T, E> }>;
export function badRequest<T, E>(errors?: ZodFormattedError<T, E> | string) {
  return json(
    { message: 'Bad Request', ...(errors && { errors }) },
    { status: 400 },
  );
}

方案2:给错误对象添加类型标注

如果不想修改重载结构,可在调用时明确标记错误对象的类型:

// 替换为你实际校验的Schema对应的类型
const zodErrors: ZodFormattedError<{ name: string }> = {
  _errors: [
    {
      code: 'invalid_type',
      expected: 'string',
      received: 'number',
      path: ['name'],
      message: 'Expected string, received number',
    },
  ],
};

const myRequest = badRequest(zodErrors);

方案3:调用时显式指定泛型参数

直接在调用函数时指定泛型参数,强制TypeScript使用泛型重载:

const myRequest = badRequest<{ name: string }>({
  _errors: [
    {
      code: 'invalid_type',
      expected: 'string',
      received: 'number',
      path: ['name'],
      message: 'Expected string, received number',
    },
  ],
});

验证效果

修正后,TypeScript将正确识别三种调用场景的返回类型:

  • 无参调用:TypedResponse<{ message: string }>
  • 传入字符串:TypedResponse<{ message: string; errors: string }>
  • 传入Zod错误对象:TypedResponse<{ message: string; errors: ZodFormattedError<T> }>

内容的提问来源于stack exchange,提问作者J. Hesters

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 07:25:18