24 lines
888 B
TypeScript
24 lines
888 B
TypeScript
type ParseUrlParamsRaw<Url> = Url extends `${infer Start}/${infer Rest}`
|
|
? ParseUrlParamsRaw<Start> & ParseUrlParamsRaw<Rest>
|
|
: Url extends `{${infer Param}}`
|
|
? { [P in Param]: string }
|
|
: {};
|
|
|
|
// ParseUrlParamsRaw allows passing objects with any keys (i.e. `{name: "foo"}`) even though
|
|
// an empty object is expected (`{}`). This type constraint enforces this by checking if
|
|
// the result of ParseUrlParamsRaw<Url> is `{}`. `keyof {}` evaluates to `never`, so
|
|
// when `{}` is evaluated an empty Record is expected, otherwise the result of
|
|
// ParseUrlParamsRaw is expected.
|
|
type ParseUrlParams<Url> = keyof ParseUrlParamsRaw<Url> extends never
|
|
? Record<string, never>
|
|
: ParseUrlParamsRaw<Url>;
|
|
|
|
function navigate<P extends string>(path: P, params: ParseUrlParams<P>) {
|
|
// ...
|
|
}
|
|
|
|
function main() {
|
|
navigate("/hello", {});
|
|
navigate("/hello/{name}", { name: "foo" });
|
|
}
|