Skip to content

Instantly share code, notes, and snippets.

@derrh
Created November 2, 2021 18:02
Show Gist options
  • Save derrh/c873e3383038ff0a1d3a4e743748cf86 to your computer and use it in GitHub Desktop.
Save derrh/c873e3383038ff0a1d3a4e743748cf86 to your computer and use it in GitHub Desktop.
type RouteLeaf = string | number | bigint | boolean | null | undefined
// there's probably a tidier way to get around TS's lack of support for recursive `type`'s
type RouteBranch<SubBranch = RouteLeaf> = Record<string | number | symbol, RouteLeaf | SubBranch>
type RouteComponent =
| RouteLeaf
| RouteBranch<RouteBranch>
| RouteBranch<RouteBranch<RouteBranch>>
| RouteBranch<RouteBranch<RouteBranch<RouteBranch>>>
| RouteBranch<RouteBranch<RouteBranch<RouteBranch<RouteBranch>>>>
| RouteBranch<RouteBranch<RouteBranch<RouteBranch<RouteBranch<RouteBranch>>>>>
type Route<Map extends RouteComponent> = Map extends Record<infer Key, RouteComponent>
? Key extends RouteLeaf
? `/${Key}${Route<Map[Key]>}`
: never
: Map extends RouteLeaf
? `/${Map}`
: never
type DivvyRoute = Route<{
"wallet": number,
"transactions": Record<number, 'summary' | 'details'>,
"potatoes": "russet" | "yukon"
}>
function theWay(n: number) {
const path: DivvyRoute = `/transactions/${n}/summary`
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment