My question is similar to Types from both keys and values of object in Typescript, but with an additional layer of nesting:
interface Outer {
a: {
b: number
},
c: {
d: string
}
}
And I'm only looking to retrieve the union type of all values, here number | string
.
Here's my stab:
type Values<T extends Record<string, any>> = T[keyof T]; // From previous SO answer
type InnerValues<
T extends Record<string, Record<string, any>>,
K extends keyof T
> = T[K][keyof T[K]];
type All = Values<Outer>;
type In = InnerValues<Outer, keyof Outer>; // expected number|string
but I have an error saying Outer
doesn't have an index type.
Playground link.
T[K][keyof T[K]]
will not work because T[K]
will be a union of all possible values in T
(well the values specified by K
anyway) and keyof T[K]
will probably end up being never
if the values have no common keys.
The solution is to take each constituent in the union T[K]
and get its possible values. We can do this using a distributive conditional type
interface Outer {
a: {
b: number;
};
c: {
d: string;
};
}
type DistributiveValues<T extends Record<string, any>> = T extends T ? T[keyof T] : never;
type InnerValues<
T extends Record<keyof T, object>,
K extends keyof T
> = DistributiveValues<T[K]>;
type In = InnerValues<Outer, keyof Outer>; // is number|string
play
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With