0%
September 5, 2023

Routing Schema for Frontend Project

react

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!