getting combined type of object values
I have a case, where I have nested objects and defined types of each key like so:
type One = {
a: number
b: string
}
type Two = {
c: boolean
d: Function
}
type Root = {
one: One
two: Two
}
When I merge/flatten values of object with Root type, I will get something like One & Two. Currently I couldn't find any way to accomplish this with TypeScript types. The only thing I could think of is:
type Flattened = Root[keyof Root]
However, in this case I am getting One | Two which is never, because it searches common inside of One and Two. I wish there is a keyword like valuesof and when I use it, I get combined types of object values.
Would be very useful when setting types for flattened objects. One possible pitfall may be correct way of overriding/merging common props of inner object types.
function flattenIt<T extends object>(o: T): valuesof T {
return Object.keys(o).reduce((c, key) => ({ ...current, ...o[key] }), {})
}
type One = {
a: number
b: string
}
type Two = {
c: boolean
d: Function
}
type Root = {
one: One
two: Two
}
const flattened = flattenIt<Root>(someObj)
flattened. // suggests a | b | c | d
My suggestion meets these guidelines:
@iamawebgeek Look at this example with flat of object(this is hack - I agree):
https://stackoverflow.com/a/51438474/6515842
Your example:
function flattenIt<T extends object>(o: T): PickAndFlatten<T, keyof T> {
// your implementation
}
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
type PickAndFlatten<T, K extends keyof T> = UnionToIntersection<T[K]>;
let flattern = flattenIt<Root>(obj);
flattern. // suggests a | b | c | d
@vitalics thank you for pointing that out, I have no idea how, but that works exactly how I expected
Most helpful comment
@iamawebgeek Look at this example with flat of object(this is hack - I agree):
https://stackoverflow.com/a/51438474/6515842
Your example: