#How to map Object to List of key / Value Pairs

10 messages · Page 1 of 1 (latest)

stray cradle
#

It is easy to create a type like that:

type Foo = { a: 1; b: 2 }

I am searching for a way to map such a type to its corresponding list of of key/value pairs - the same thing one gets from Object.entries. But I neither would like to end up with [string, number][], nor ['a'|'b', 1 | 2] ([keyof Foo, Foo[keyof Foo]][]), I am searching for a result that is: [a,1] | [b,2] .

Is something like that possible?

bold oasis
#

it's very much possible:

nova nebulaBOT
#
type KeyValuePairs<T> = {
  [K in keyof T]: [K, T[K]]
}[keyof T]

type Example = KeyValuePairs<{ a: 1; b: 2 }>
//   ^? - type Example = ["a", 1] | ["b", 2]
stray cradle
#

Yeah! Cool! That pretty cool! Thanks. Even though it wasn't part of my question, but would it also be possible to get [[a,1],[b,1]] - a tuple - such each pair has to appear exactly one time?

bold oasis
#

yes but it relies on some dark magic that is generally best to avoid. unions don't have an inherent ordering (and neither do object properties) so there's no logical reason why it should be [[a,1],[b,1]] rather than [[b,1],[a,1]]

#

search for "union to tuple" though

#

we might have a snippet here... 1 sec

#

!:u2t

nova nebulaBOT
#
joshcena63#0
type U2I<U> = (
  U extends U ? (arg: U) => 0 : never
) extends (arg: infer I) => 0
  ? I
  : never

// For homogeneous unions, it picks the last member
type OneOf<U> = U2I<
  U extends U ? (x: U) => 0 : never
> extends (x: infer L) => 0
  ? L
  : never

type U2T<U, L = OneOf<U>> = [U] extends [never]
  ? []
  : [...U2T<Exclude<U, L>>, L]```
bold oasis
#

you can get fancier and generate [[a,1],[b,1]] | [[b,1],[a,1]], which sidesteps the ambiguous ordering problem. the resulting type quickly gets very large though as there's a combinatorial explosion