4

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)

2
  • 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? Commented Feb 8, 2019 at 20:11
  • Compile time :) The answer below shows the solution. Commented Feb 8, 2019 at 20:18

1 Answer 1

10

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>
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, this is working! I'll accept this as the answer in a few minutes, once I'm able to.
Very nice! Btw [K in T[number]['key']]: K this will woks the same as Extract<T[number], { key : K}>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.