I have defined a Module with a MetaData
type and a mapping object for child/nested Modules:
type Module<T, C extends Children> = {
metaData: T;
children: C;
};
type Children = {
[key: string]: Module<any, any>;
}
type ExtractMetaData<M extends Module<any, any>> = M extends Module<infer T, any> ? T : never;
type ExtractChildren<M extends Module<any, any>> = M extends Module<any, infer C> ? C : never;
Next, I create three modules, A, B, and C, where C is a child of B and B is a child of A:
type C = Module<number, {}>;
type B = Module<boolean, {
c: C;
}>;
type A = Module<string, {
b: B;
}>;
Now, I need a utility type called
AllMetaData<T extends Module>
that will give me a union of all the MetaData
types in a Module tree. For example, AllMetaData<C>
should return the type number
, AllMetaData<B>
should be number | boolean
, and AllMetaData<A>
should be number | boolean | string
.
Here's my attempt at creating this type:
type AllMetaData<
MODULE extends Module<any, any>,
CHILDREN = ExtractChildren<MODULE>,
METADATA = ExtractMetaData<MODULE>,
> =
| METADATA
| {
[KEY in keyof CHILDREN]: CHILDREN[KEY] extends Module<any, any>
? ExtractMetaData<MODULE>
: never;
}[keyof CHILDREN];
However, when I try to use this type:
type Result = AllMetaData<A>;
The Result
turns out to be just string
, instead of the expected union of all the MetaData
types in A's tree.
What could be causing this issue with my AllMetadata
type?