TypeScript路由函数Middleware类型校验异常问题求助
自定义路由函数的TypeScript类型校验异常
问题描述
- 自定义
route函数中,middlewares参数始终触发类型错误,但直接使用ValidateMiddlewares类型标注变量时(如代码第72、75行)可正常校验 - 调用
route函数时(第98、107行)会报错,但错误提示标记整个middlewares数组,而非具体存在问题的中间件(例如AnalyticMiddleware)
相关代码
abstract class BaseMiddleware< Input extends Record<string, any>, Output extends Record<string, any>, > { abstract index(data: Input): Output } abstract class BaseController<Input extends Record<string, any>> { abstract index(data: Input): void } class AuthMiddleware extends BaseMiddleware<{}, { userID: number }> { index(data: {}) { return { userID: 1, } } } class UserPopulateMiddleware extends BaseMiddleware<{ userID: number }, { username: string }> { index(data: { userID: number }) { return { username: `getUsernameFromUserID(${data.userID})`, } } } class AnalyticMiddleware extends BaseMiddleware<{ userID: number; username: string }, {}> { index(data: { userID: number; username: string }) { return {} } } class AuthorizedController extends BaseController<{ userID: number }> { index(data: { userID: number }) {} } class UserPopulatedController extends BaseController<{ userID: number; username: string }> { index(data: { userID: number; username: string }) {} } class Controller extends BaseController<{}> { index(data: {}) {} } type MiddlewareArray = BaseMiddleware<any, any>[] type ValidateMiddlewares< T extends MiddlewareArray, V extends MiddlewareArray = T, Input extends Record<string, any> = Record<string, never>, Results extends any[] = [], > = V extends [BaseMiddleware<Input, infer Output>, ...infer Tail extends MiddlewareArray] ? ValidateMiddlewares<T, Tail, Input & Output, [...Results, V[0]]> : V extends [BaseMiddleware<any, infer Output>, ...infer Tail extends MiddlewareArray] ? ValidateMiddlewares<T, Tail, Input, [...Results, BaseMiddleware<Input, Output>]> : Results type MergeMiddlewaresOutput< T extends MiddlewareArray, Input extends Record<string, any> = {}, > = T extends [BaseMiddleware<any, infer Output>, ...infer Tail extends MiddlewareArray] ? MergeMiddlewaresOutput<Tail, Output & Input> : Input type R1 = ValidateMiddlewares< [BaseMiddleware<{}, { token: string }>, BaseMiddleware<{ a: string }, { userID: number }>] > type R2 = ValidateMiddlewares< [BaseMiddleware<{}, { userID: number }>, BaseMiddleware<{ userID: number }, { username: string }>] > type R3 = ValidateMiddlewares<[AuthMiddleware, UserPopulateMiddleware]> type R4 = ValidateMiddlewares<[UserPopulateMiddleware]> type R5 = ValidateMiddlewares<[AuthMiddleware, AnalyticMiddleware]> // 此处校验正常,仅AnalyticMiddleware会被标记错误——它需要userID和username输入,但AuthMiddleware只输出userID const R5: ValidateMiddlewares<[AuthMiddleware, AnalyticMiddleware]> = [ new AuthMiddleware(), new AnalyticMiddleware(), ] // 此处校验正常 const R6: ValidateMiddlewares<[AuthMiddleware, UserPopulateMiddleware, AnalyticMiddleware]> = [ new AuthMiddleware(), new UserPopulateMiddleware(), new AnalyticMiddleware(), ] type ValidateController< Controller extends BaseController<{}>, Middlewares extends MiddlewareArray | [], > = Controller extends BaseController<infer Data> ? MergeMiddlewaresOutput<Middlewares> extends Data ? Controller : never : never type C1 = ValidateController< BaseController<{ userID: number }>, [BaseMiddleware<{}, { userID: number; username: string }>] > // 问题函数 const route = <Middlewares extends MiddlewareArray, Controller extends BaseController<any>>( path: string, middlewares: ValidateMiddlewares<Middlewares>, controller: ValidateController<Controller, Middlewares>, ) => { // 路由实现 } route('test', [new AuthMiddleware(), new UserPopulateMiddleware()], new UserPopulatedController()) // 应该通过校验 route('test', [], new Controller()) // 通过校验 route('test', [], new UserPopulatedController()) // 错误 route('test', [new AuthMiddleware()], new UserPopulatedController()) // 错误 route('test', [new UserPopulateMiddleware()], new AuthorizedController()) // 错误 route('test', [new UserPopulateMiddleware()], new AuthorizedController()) // 错误 route('test', [], new AuthorizedController()) // 错误 // 此处报错符合预期,但错误提示标记整个数组而非AnalyticMiddleware route('test', [new AuthMiddleware(), new AnalyticMiddleware()], new AuthorizedController()) // 错误
内容的提问来源于stack exchange,提问作者kennarddh
相关产品推荐
相关产品推荐

