Skip to content

Instantly share code, notes, and snippets.

@crutchcorn
Last active November 14, 2022 17:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save crutchcorn/78a3f9375e00d4a3634a9e01e051146c to your computer and use it in GitHub Desktop.
Save crutchcorn/78a3f9375e00d4a3634a9e01e051146c to your computer and use it in GitHub Desktop.
// OK
const firstRoute = ":test"; // Or ":test/" or "/:test" or "other/:test", etc
fillRoute(firstRoute, {
test: "hello",
});
// Type error - not enough params
const secondRoute = ":test/:other";
fillRoute(secondRoute, {
test: "hello",
});
// Type error - too many params
const thirdRoute = ":test/:other";
fillRoute(thirdRoute, {
test: "hello",
other: "blah",
last: "123",
});
type GetRouteParams<T extends string> = T extends `:${infer Name}/${infer Rest}`
? Record<Name, string> & GetRouteParams<Rest>
: T extends `:${infer OnlyName}`
? Record<OnlyName, string>
: T extends `${string}/${infer MoreRest}`
? GetRouteParams<MoreRest>
: Record<never, never>;
function fillRoute<Route extends string>(
route: Route,
params: GetRouteParams<Route>
) {
const routeSegments = route.split("/");
return routeSegments
.map((routeSegment) => {
if (!routeSegment.startsWith(":")) return routeSegment;
const paramName = routeSegment.replace(/^:/, "");
return params[paramName];
})
.join("/");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment