NeoBean
NeoBean11mo ago

How to Type a Middleware factory?

Lemme first show you what I want, so you can get the gist of it. (Consider me less experienced in typescript)
publicProcedure
.input(z.object({ test: z.boolean() }))
.use(middlewareFactory( /** TO GET INPUT TYPECHECKING HERE */ ))
publicProcedure
.input(z.object({ test: z.boolean() }))
.use(middlewareFactory( /** TO GET INPUT TYPECHECKING HERE */ ))
This is what I put together. This almost works
/// types
type CustomPParams<T> = ProcedureParams<AnyRootConfig,unknown,unknown,T,unknown,unknown,unknown>
type MiddlewareFactory = <T>(input: T) => MiddlewareFunction<CustomPParams<T>, ProcedureParams>

/// a middleware factory
export const middlewareFactory: MiddlewareFactory = input => ({ next }) => { return next() }
/// types
type CustomPParams<T> = ProcedureParams<AnyRootConfig,unknown,unknown,T,unknown,unknown,unknown>
type MiddlewareFactory = <T>(input: T) => MiddlewareFunction<CustomPParams<T>, ProcedureParams>

/// a middleware factory
export const middlewareFactory: MiddlewareFactory = input => ({ next }) => { return next() }
I get autocompletion in vscode, but when I press tab and proceed with the autocompletion, I get an error that looks like this (the screenshot attached). Feels like i'm in the right path but cant exactly make a solid type out it. Now, for my very specific use case, i did make an workaround by making that T generic partial
type MiddlewareFactory = <T>(input: Partial<T>) => MiddlewareFunction<CustomPParams<T>, ProcedureParams>
type MiddlewareFactory = <T>(input: Partial<T>) => MiddlewareFunction<CustomPParams<T>, ProcedureParams>
But this feels like a half measure. And provided that different validation libs might affect the type of input in subtle ways, I need to know how to properly type this thing. Thank you
No description
1 Reply
NeoBean
NeoBean11mo ago
please expand this thread panel horizontally. easier to read without the code getting wrapped Well, ctx doesnt get typed in this way, look at this code
type CustomPParams<T> = ProcedureParams<
AnyRootConfig,
MyCustomContext, /** PUTTING CONTEXT TYPE HERE DOESNT WORK */
unknown,
T,
unknown,
unknown,
unknown
>
type CustomPParams<T> = ProcedureParams<
AnyRootConfig,
MyCustomContext, /** PUTTING CONTEXT TYPE HERE DOESNT WORK */
unknown,
T,
unknown,
unknown,
unknown
>
I think I'm supposed to use t.middleware, this way I do get the context/meta types, but i cant seem to make a custom factory. Modifying above code like this throws an error
export const middlewareFactory: MiddlewareFactory = input => t.middleware(({ next }) => { return next() })
export const middlewareFactory: MiddlewareFactory = input => t.middleware(({ next }) => { return next() })
MiddlewareBuilder is not assignable .. such and such