3

Consider a tuple like this:

type MyTuple = [A, B];

where A and B both have an attribute named key. For instance,

interface A = {
  key: 'sandwiches'
}

interface B = {
  key: 'pasta'
}

I desire the following interface:

interface Result {
  sandwiches: A;
  pasta: B;
}

Is there a way to do this dynamically?

I'm thinking that, if this is achievable, it might look something like:

type MapTuple<T> = {
  [K in keyof T]: T[K]["key"]
}

but this doesn't work.

This question is the inverse of Typescript: object type to array type (tuple)

jamesplease
  • 12,547
  • 6
  • 47
  • 73
  • I think typescript typing is only available at compile-time -- what do you mean with 'Is there a way to do this dynamically?' Do you just want to have the Result interface inferred at compile-time or are you looking for a run-time solution? – Simon Groenewolt Feb 08 '19 at 20:11
  • Compile time :) The answer below shows the solution. – jamesplease Feb 08 '19 at 20:18

1 Answers1

9

This will produce the desired effect. You need to map over all the key properties of the tuple and extract the tuple member for each key :

type MyTuple = [A, B];

interface A {
  key: 'sandwiches'
}

interface B {
  key: 'pasta'
}


type MapTuple<T extends Array<{ key: string }>> = {
  [K in T[number]['key']]: Extract<T[number], { key : K}>
}

type R = MapTuple<MyTuple>
Titian Cernicova-Dragomir
  • 230,986
  • 31
  • 415
  • 357