TypeScript如何为顺序执行的中间件数组添加类型约束?
TypeScript 类型安全的中间件链实现
问题描述
给定如下抽象中间件类:
export abstract class Middleware<T, K> { public abstract run(input: T): Promise<K>; }
其中T是run()方法的输入类型,K是输出类型。多个具体中间件需要存入数组按顺序执行,例如:
[ specificMiddleware1, specificMiddleware2, specificMiddleware3 ]
要求specificMiddleware1的输出类型K必须与specificMiddleware2的输入类型T一致,以此类推。需要在数组层面实现严格的类型安全约束,保证中间件的输入输出类型链合法。
当前方案的不足
目前采用手动维护类型的方式:
export type InputType = /* 具体类型 */; export type OutputType1 = /* 具体类型 */; export type OutputType2 = /* 具体类型 */; export type OutputType3 = /* 具体类型 */; export interface Schema { middlewares: [ // specificMiddleware1 Middleware<InputType, OutputType1>, // specificMiddleware2 Middleware<OutputType1, OutputType2>, // specificMiddleware3 Middleware<OutputType2, OutputType3>, ] }
该方案虽然可行,但随着中间件数量增加,需要手动定义大量中间类型,维护成本飙升,且无法自动校验类型匹配,存在类型不兼容的风险。
尝试过的无效方案
曾尝试以下类型定义,但类型操作不生效,也无法适配泛型:
type Numbers = { 0; 1; 2; }; export type MiddlewareList = { [Index in keyof Numbers]: Middleware< ReturnType<MiddlewareList[Index - 1]['run']>, unknown >; };
已实现的粗糙解决方案
目前实现了一个基础版本,欢迎提出改进建议:
// 从Promise<T>中提取T类型 export type ExtractPromiseResult<T = PromiseLike<any>> = T extends PromiseLike<infer R> ? R : never; // 从Middleware的run方法中提取返回值K的类型 export type ExtractReturnType<T> = ExtractPromiseResult<ReturnType<T['run']>> export type MiddlewareChain< InputType, Middleware1 extends Middleware<unknown, unknown>, Middleware2 extends Middleware<unknown, unknown> = never, // 默认值never实现可选 Middleware3 extends Middleware<unknown, unknown> = never, // 默认值never实现可选 // 可按需扩展更多泛型参数 > = [ Middleware<InputType, ExtractReturnType<Middleware1>>, Middleware<ExtractReturnType<Middleware1>, ExtractReturnType<Middleware2>>?, Middleware<ExtractReturnType<Middleware2>, ExtractReturnType<Middleware3>>?, // 可按需扩展更多元素 ];
内容的提问来源于stack exchange,提问作者George Lazu
相关产品推荐
相关产品推荐

