如何在应用中深层传递泛型类型?框架无关中间件问题
问题分析与修复方案
你的核心问题是泛型没有在类型层级间正确关联:当前UmbressOptions里的ipAddressExtractor是一个独立的泛型方法,TypeScript无法将你调用umbress<R,S>时指定的R和这个方法的泛型R绑定,导致传入的ipAddressExtractor无法推断出request的具体类型。
具体修改步骤:
将
UmbressOptions改为泛型类型
把原本方法级的泛型提到类型层面,让整个选项类型依赖外部传入的R:type UmbressOptions<R> = { ipAddressExtractor(request: R): string; };调整
ProcessorService的类型依赖
让类的泛型R关联到UmbressOptions,确保构造函数接收的选项是和当前类泛型匹配的类型:class ProcessorService<R, S> { #options: UmbressOptions<R>; constructor(userOptions: UmbressOptions<R>) { this.#options = userOptions; } async process(request: R): Promise<S | void> { // 这里不需要再给ipAddressExtractor传泛型,类型已经绑定 const ipAddress = this.#options.ipAddressExtractor(request); } }修正
umbress函数的参数类型
让函数的泛型R传递给UmbressOptions,确保传入的选项和指定的泛型一致:function umbress<R, S>(userOptions: UmbressOptions<R>): (request: R, response: S) => void { const processor = new ProcessorService<R, S>(userOptions); return processor.process; }
修改后的完整代码:
// 假设已经导入express的Request/Response类型 import { Request, Response } from 'express'; type UmbressOptions<R> = { ipAddressExtractor(request: R): string; }; class ProcessorService<R, S> { #options: UmbressOptions<R>; constructor(userOptions: UmbressOptions<R>) { this.#options = userOptions; } async process(request: R): Promise<S | void> { const ipAddress = this.#options.ipAddressExtractor(request); } } function umbress<R, S>(userOptions: UmbressOptions<R>): (request: R, response: S) => void { const processor = new ProcessorService<R, S>(userOptions); return processor.process; } // 此时request会自动推断为express.Request类型 umbress<Request, Response>({ ipAddressExtractor: (request) => request.headers['x-forwarded-for'] as string, });
关键说明:
- 把泛型从方法级别提升到类型级别,让
UmbressOptions和外部指定的R强绑定,TypeScript就能正确推断ipAddressExtractor的参数类型。 - 移除了
ipAddressExtractor方法上的泛型声明,因为类型已经通过UmbressOptions<R>传递过来,无需重复指定。
内容的提问来源于stack exchange,提问作者JamesJGoodwin
相关产品推荐
相关产品推荐

