3

How to transform union of similar objects to object type using TypeScript typings?

Input

type I = {
  key: 'foo',
  value: Foo,
} | {
  key: 'bar',
  value: Bar,
};

Output

type O = {
  foo: Foo,
  bar: Bar,
};

I am not sure it is possible. But who knows? Note that the task is not a duplicate to that.

jcalz
  • 264,269
  • 27
  • 359
  • 360
avdotion
  • 105
  • 8
  • 3
    That's not an intersection. – Jared Smith Dec 20 '20 at 00:01
  • It's not clear what the algorithm would even be to get from your "input" to your "output" unless you had a type that happened to be a union of a bunch of types with key properties of type string and value properties of various types. And how would you use this output? You want an expression that produces `O` from `I`? How does that help you? `O` is not that hard to type into your code -- you did it above. So yeah, see whether you can improve or clarify the question, I'd say. – David P. Caldwell Dec 20 '20 at 00:07

1 Answers1

5

In TypeScript 4.1 this is a straightforward mapped type with key remapping. You can iterate over each member T of the I union (it's a union, not an intersection) and look up the key/value types: T['key'] for the key and T['value'] for the value. Like this:

type O = { [T in I as T['key']]: T['value'] };
/* type O = {
    foo: Foo;
    bar: Bar;
} */

Playground link to code

jcalz
  • 264,269
  • 27
  • 359
  • 360