Typescript: Feature request: get type of object values

Created on 18 Dec 2018  路  2Comments  路  Source: microsoft/TypeScript

Search Terms

getting combined type of object values

Suggestion

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.

Use Cases


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.

Examples

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

Checklist

My suggestion meets these guidelines:

  • [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • [x] This wouldn't change the runtime behavior of existing JavaScript code
  • [x] This could be implemented without emitting different JS based on the types of the expressions
  • [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • [x] This feature would agree with the rest of TypeScript's Design Goals.

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:

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

All 2 comments

@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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yortus picture yortus  路  157Comments

sandersn picture sandersn  路  265Comments

kimamula picture kimamula  路  147Comments

jonathandturner picture jonathandturner  路  147Comments

rwyborn picture rwyborn  路  210Comments