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'.
问题原因
- 重载匹配顺序冲突:TypeScript按重载定义的顺序匹配调用,第一个带泛型的重载优先匹配传入的对象,但
ZodFormattedError<T>默认第二个类型参数为string(错误消息类型),与你传入的对象类型_errors元素不兼容。 - 类型推断缺失:手动构造的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
相关产品推荐
相关产品推荐

