Is there a way to pass generic types deep into my application? I am developing a middleware that needs to be compatible with any framework. I am initializing the middleware with generic values, expecting them to be passed down to internal classes and methods. However, it seems like this is not happening:
app.use(
umbress<express.Request, express.Response>({
ipAddressExtractor: (request) => request.headers['x-forwarded-for'],
// -----------------^^^^^^^^^------------------------
// The request type here should be express.Request, but it's showing as R
}),
);
The umbress
function is initialized as follows:
export default function umbress<R, S>(userOptions: UmbressOptions): (request: R, response: S) => void {
const processor = new ProcessorService<R, S>(userOptions, optionsServiceInstance, ipBasedMitigationServiceInstance);
//------------------------------------^^^^^^----------------------------------
// Passing down generic values here
return processor.process;
}
In addition, the ProcessorService
also accepts generics:
export class ProcessorService<R, S> {
The method process
uses these generics for argument types:
async process(request: R, response: S): Promise<S | void> {
const ipAddress = this.#options.ipAddressExtractor<R>(request);
The ipAddressExtractor
is defined inside the type
object like this:
ipAddressExtractor<R>(request: R): string;
Have I overlooked something? How can I resolve this issue?
EDIT: Here's a complete example that you can run:
type UmbressOptions = {
ipAddressExtractor<R>(request: R): string;
};
class ProcessorService<R, S> {
#options: UmbressOptions;
constructor(userOptions: UmbressOptions) {
this.#options = userOptions;
}
async process(request: R): Promise<S | void> {
const ipAddress = this.#options.ipAddressExtractor<R>(request);
}
}
function umbress<R, S>(userOptions: UmbressOptions): (request: R, response: S) => void {
const processor = new ProcessorService<R, S>(userOptions);
// ------------------------------------^^^^^^----------------------------------
// passing down generic values here
return processor.process;
}
umbress<Request, Response>({
ipAddressExtractor: (request) => request.headers['x-forwarded-for'],
// -----------------^^^^^^^^^-----------^^^^^^^^--------------------
// `request` implicitly has type `any` because R is not set to a default value
});
You might need to install npm i defaults cache-manager
for full type resolution.