Routing Schema as a Type Variable
Let's define a routing schema by defining, sequentially, which value is possible to appear:
export type NavigationRouteSchema = { value: "/buyer" | "/supplier", next: { value: "order", next: { value: Oid next: { value: "" | "requirements" | "quotation" | "sampling" | "freight" } | { value: "contract", next: { value: Oid } } } } | { value: "projects", } | { value: "correspondence-dashboard", next: { value: "mailchains", next: { value: "mailchainOid", next: { value: Oid } } } | { value: "unlinked-emails", next: { value: "emailOid", next: { value: Oid } } } } };
For example,
/buyer/order/abcdsfds123123/contract/6dsf456sd6f4s
is among the possible choices.
Let's define the following type
:
Define Custom Type of Tuples from the Schema
type RouteBreakdown<T> = T extends { value: infer U, next: infer V } ? [U, ...RouteBreakdown<V>] : T extends { value: infer U } ? [U] : never export type ClientNavigation = RouteBreakdown<NavigationRouteSchema>;
Then by hovering ClientNavigation
:
type ClientNavigation = ["/buyer" | "/supplier", "order", string, "" | "requirements" | "quotation" | "sampling" | "freight"] | ["/buyer" | "/supplier", "order", string, "contract", string] | [...] | [...] | [...]
which consists of all possible tuples of values
in our NavigationRouteSchema
with correct sequential order.
Construct Navigation Route with ZERO Chance of Making Mistake
Now we define
const getNavigationRoute = (...args: ClientNavigation) => { return args.join("/"); };
which simply assembles the values into a correct URL for navigation.
-
We are 100% confident that our path is correct without hard-coding. Why?
-
First all value can be auto-completed:
-
Any route that is not among our tuple of string-types will trigger an error:
-
Apart from auto-complete suggestions, there will also be a pop-up indicating the type at the current positional argument:
-
From now on any change of routes requirement becomes extremely trivial!