Created
August 3, 2022 15:06
-
-
Save gabrielelana/24d5715d26c48b2859217a112992f7f6 to your computer and use it in GitHub Desktop.
Typescript utility type to parse route parameters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Tuple<X, Y> = [X, Y] | |
type Equal<X, Y> = | |
(<T>() => T extends X ? 1 : 2) extends | |
(<T>() => T extends Y ? 1 : 2) ? Tuple<true, Y> : Tuple<false, Y> | |
type Assert<T extends Tuple<true, any>> = T[1];// | |
// P = collecting param names | |
// N = current param name | |
// I = true if we are collecting a name | |
type RouteParameters<R extends string, P extends string = never, N extends string = "", I extends boolean = false> = | |
R extends `${infer C}${infer T}` | |
? C extends ":" | |
? RouteParameters<T, P, N, true> | |
: C extends "/" | "." | "-" | |
? I extends true | |
? RouteParameters<T, P|N, "", false> | |
: RouteParameters<T, P, N, I> | |
: I extends true | |
? RouteParameters<T, P, `${N}${C}`, I> | |
: RouteParameters<T, P, N, I> | |
: R extends `${infer C}` | |
? C extends "" | |
? I extends true | |
? {[K in P | `${C}${N}`]: string} | |
: {[K in P]: string} | |
: {[K in P]: string} | |
: {[K in P]: string} | |
type tests = [ | |
Assert<Equal<{}, RouteParameters<"">>>, | |
Assert<Equal<{}, RouteParameters<"/foo">>>, | |
Assert<Equal<{}, RouteParameters<"/foo/bar">>>, | |
Assert<Equal<{foo: string}, RouteParameters<"/:foo">>>, | |
Assert<Equal<{foo: string}, RouteParameters<"/:foo/">>>, | |
Assert<Equal<{foo: string}, RouteParameters<"/:foo/bar">>>, | |
Assert<Equal<{foo: string}, RouteParameters<"/bar/:foo">>>, | |
Assert<Equal<{foo: string}, RouteParameters<"/bar/:foo/baz">>>, | |
Assert<Equal<{foo: string, bar: string}, RouteParameters<"/:foo/:bar">>>, | |
Assert<Equal<{foo: string, bar: string, baz: string}, RouteParameters<"/:foo/:bar/:baz">>>, | |
Assert<Equal<{userId: string, bookId: string}, RouteParameters<"/users/:userId/books/:bookId">>>, | |
Assert<Equal<{from: string, to: string}, RouteParameters<"/flights/:from-:to">>>, | |
Assert<Equal<{genus: string, species: string}, RouteParameters<"/plantae/:genus.:species">>>, | |
]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@ghost Not supported but not hard to implement