I'm trying to come up with an answer to How to type `request.query` in express using TypeScript? because I want one, myself.
In express, using string literal types the route parameters get inferred correctly. However, express has no way of specifying a strong type for its query string parameters without specifying the route template parameters directly, which means specifying all of them.
The RouteMatcher's declaration is:
export interface IRouterMatcher<
T,
Method extends 'all' | 'get' | 'post' | 'put' | 'delete' | 'patch' | 'options' | 'head' = any
> {
<
Route extends string,
P = RouteParameters<Route>,
ResBody = any,
ReqBody = any,
ReqQuery = ParsedQs,
Locals extends Record<string, any> = Record<string, any>
>(
// tslint:disable-next-line no-unnecessary-generics (it's used as the default type parameter for P)
path: Route,
// tslint:disable-next-line no-unnecessary-generics (This generic is meant to be passed explicitly.)
...handlers: Array<RequestHandler<P, ResBody, ReqBody, ReqQuery, Locals>>
): T;
//...
}
I would like to create an identity wrapper function, withQS, that will let me specify the ReqQuery parameter alone and infer the remaining template types.
const withQS = <
ReqQuery extends QueryString.ParsedQS,
/* TODO */
>(path: /* TODO */, ...handlers: /* TODO */): /* TODO */ =>
[ path, ...handlers ];
app.get(...withQs<{ foo: 'bar' | 'baz' }>(
('some/:route/:param', (req, res, next) => {
const { foo } = req.query;
// knows foo is 'bar' or 'baz'
const { route, param } = req.params;
// knows that route and param are the only properties
}
);
An alternative would be to have withQS wrap each handler, but that's less desirable.
Ideas? TS Playground
expressI assume we shouldn't need dependencies on it to answer the question. If so, please provide a minimal reproducible example that clearly demonstrates the issue you are facing. Ideally someone could drop the code into a standalone IDE like The TypeScript Playground (link here!) and immediately get to work solving the problem without first needing to re-create it. So there should be no pseudocode, typos, unrelated errors, or undeclared types or values. If not, maybe we should put theexpresstag on it?