Gergő Horváth
Gergő Horváth

Reputation: 3705

Typescript: how to define an array of possible keys in type arguments?

My plan is to have:

enum hobbies {
  music = 'music',
  sports = 'sports'
}

type Hobbies <T extends Array<keyof typeof hobbies>> = {
  [key in T]: number
}

type Musician = {
  hobbies: Hobbies<["music"]>
}

type Racer = {
  hobbies: Hobbies<["racing"]> //errors, fine
}

const musician: Musician = {
  hobbies: {
    music: 2,
    racing: 1 //should error but it doesn't
  }
}

Playground

The thing is that it actually does throw an error, but it does for key in T as well as it's not valid.

So it doesn't error if I define Musician with hobbies.racing

Any solutions for that?

Upvotes: 0

Views: 41

Answers (1)

Aleksey L.
Aleksey L.

Reputation: 37918

Doesn't strictly answer the question, but you can use union type instead of array:

enum hobbies {
  music = 'music',
  sports = 'sports'
}

type Hobbies <T extends keyof typeof hobbies> = {
  [key in T]: number
}

type Musician = {
  hobbies: Hobbies<"music">
}

type Racer = {
  hobbies: Hobbies<"racing"> //errors, fine
}

const musician: Musician = {
  hobbies: {
    music: 2,
    racing: 1 //now errors
  }
}

To specify multiple allowed keys just use the union type:

hobbies: Hobbies<"music" | "sports">

Playground


To answer original question and make the array work:

type Hobbies <T extends Array<keyof typeof hobbies>> = {
  [key in T[number]]: number
}

Pay attention to key in T[number] - key is on of array values

Playground

Upvotes: 1

Related Questions