I am currently working on creating a function that can handle a recursive object/array structure where each node contains a "name" and optionally, "children". My goal is to have a function that transforms this recursive structure into a type-safe object. The keys of the new object will be the recurring "name"s, ensuring compile-time errors if an invalid key is accessed.
So far, I have managed to recognize the top-level names (names "a" and "b") in such a way that 'flat' would be identified as
Record<"a" | "b", RouteConfigItem<"a" | "b">>
.
type RouteConfigItem<Keys> = {
name: Keys;
path: string;
children?: Array<RouteConfigItem<Keys>>;
}
type RouteConfig<Keys> = RouteConfigItem<Keys>[];
function getFlat<Keys>(routeConfig: RouteConfig<Keys>): Record<Keys, RouteConfigItem<Keys>> {
// Implementation details are not crucial at the moment.
return routeConfig as Record<Keys, RouteConfigItem<Keys>>;
}
const flat = getFlat([{
name: 'a',
path: 'a',
}, {
name: 'b',
path: 'b',
children: [{
name: 'c',
path: 'c',
}]
}] as const);
My challenge now lies in figuring out how to extend this functionality to include non-top-level names as well. Striving for proper types without focusing on implementation specifics within the body of getFlat()
, I aim for flat
to be recognized as
Record<"a" | "b" | "c", RouteConfigItem<"a" | "b" | "c">>
.
Just a note, while this code example seems to work in my WebStorm environment, it does not function in typescriptlang.org/play, hence the reason for not providing a link.