TypeScript泛型自定义路由创建函数类型兼容问题求助
问题分析与解决方案
错误原因
你遇到的类型不匹配问题由两个核心原因导致:
1. Response 类型签名不匹配
你的 Response 类型定义只接受 data 单个参数:
export type Response<Data = unknown> = (data: Data) => RouteResponse<Data>;
但 Route.Response 静态方法返回的函数包含可选的 errors 参数:
static Response<Data = unknown>() { return (data: Data, errors?: RouteResponseError[]) => { return new RouteResponse(data, errors); }; }
两者签名不一致,导致TypeScript认为返回的函数不符合 Response 类型。
2. 泛型约束与类型推断限制
createRoutes 的泛型约束使用了 RouteData<HttpMethod> 的默认 Responses 类型(Record<PropertyKey, Response<unknown>>),而函数参数逆变的特性导致:
Response<{ success: true }>要求传入{ success: true }类型的参数Response<unknown>可以接受任意类型的参数- 逆变规则下,更具体的函数类型(
Response<{ success: true }>)无法赋值给更宽泛的函数类型(Response<unknown>)
同时,createRoutes 返回类型的定义错误地将所有路由的 Method 和 Responses 合并为联合类型,而非每个路由对应各自的具体类型。
解决方法
步骤1:修正 Response 类型签名
更新 Response 类型,加入可选的 errors 参数,使其与 Route.Response 返回的函数签名一致:
export type Response<Data = unknown> = (data: Data, errors?: RouteResponseError[]) => RouteResponse<Data>;
步骤2:调整泛型定义以支持精确类型推断
修改 RouteData 的泛型定义,去掉 Responses 的默认值,确保它能捕获具体的响应类型:
interface RouteData< Method extends HttpMethod, Responses extends Record<PropertyKey, Response> > { Method: Method; Path: string; Headers?: z.ZodSchema; Query?: z.ZodSchema; Body?: Method extends 'GET' | 'DELETE' ? never : z.ZodSchema; Responses: Responses; }
步骤3:修复 createRoutes 的返回类型
使用映射类型确保每个路由键对应正确的 Route 类型,而非合并为联合类型:
export const createRoutes = < RoutesData extends Record<PropertyKey, RouteData<HttpMethod, any>> >( routesData: RoutesData ) => { const routes = {} as { [K in keyof RoutesData]: Route<RoutesData[K]['Method'], RoutesData[K]['Responses']> }; for (const key in routesData) { routes[key] = new Route(routesData[key]); } return routes; };
可选优化:调整 Route 类的泛型默认值
如果需要保留默认的响应类型,可以更新 Route 类的泛型定义:
export class Route< Method extends HttpMethod, Responses extends Record<PropertyKey, Response> = Record<PropertyKey, Response<unknown>> > { // ... 原有构造函数和属性定义不变 }
验证修改后的代码
调整后的代码可以正确推断 AuthRoutes 的类型,Success 响应的类型会被正确识别为 Response<{ success: true }>,不再抛出类型错误。
内容的提问来源于stack exchange,提问作者bek
相关产品推荐
相关产品推荐

