typesafe-routes
typesafe-routes copied to clipboard
pageParams and queryParams dissociation
Hello, while using the following code:
export const pageParams = route(':id&:date', {id: stringParser, date: dateParser}, {});
I realize that parsing the route pageParams.parseParams({id:"", date:"2001-01-01"})
the route will merge the params with the queryParams, for this reason, I'm loosing the distinction typing when I want to retrieve only one of those.
in short: I expect to have the following typing
type pageParams = {
id: string
}
type pageQueryParams = {
date?: Date
}
but currently I do get a merged version of both
type params = {
id: string;
date?: Date
}
One possible dirty (?) way of getting back only the pageParams or the pageQueryParams would be to use a Pick<params, "id"> and Omit<params, "id"> to respectively hve the pageParams and the pageQueryParams. Of course the code above should rely on another type function able to identify within the string template the possible pageQueryParams keys.
Here is an idea:
type ExcludeAmpersandPrefix<S extends string> = S extends `&:${infer _}` ? never : S;
type StringToUnion<S extends string> =
S extends `:${infer T}:${infer U}` ? ExcludeAmpersandPrefix<T> | StringToUnion<`:${U}`> :
S extends `:${infer T}` ? ExcludeAmpersandPrefix<T> :
never;
Where
type Result = StringToUnion<":id:id2&:id3">; // "id" | "id2"
But of course this is taking the problem upside down (splitting after merging) while we could have the parseParams
to be a merge of pageParams and pageQueryParams.
The same apply for serializing.
Right now, we also have a problem if the pattern is "':id&:id'", i.e. a clash between 2 property names while they could be distinct.
A possible workaround is to use 2 routes, one for the pageParams ":id" and the second one for the pageQueryParams "&:date" where it will work, it's clean (single responsibilit) but then I cannot have one object to provide the route to angular i.e. I cannot use the convenient pageParams.template
.
Of course I can create a helper doing something like
function mergeTemplate(a: route, b: route){
[a.template, b.template].filter((template)=>!!template).join("/");
}
But I feel like we should have the ability to parse and serialize only the pageParams and queryPageParams if we want to from typesafe-routes.
Am I doing it wrong ?
[edit] I realize that angular won't ever need the template for the pageQueryParams