0

I am trying to specify a key name for a type from a list of options. It seems that all the options are required as keys using my approach which is not what I want. I need to specify a key name from a list of options, not require all the options to be implemented.

Property 'b' is missing in type '{ a: number; }' but required in type '{ a: number; b: number; }'.

type Options = 'a' | 'b';
type Widget = {
  name: string,
  foo: {
    [key in Options]: number
  }
}
const widget: Widget = {
  name: 'foo',
  foo: {
    a: 1,
  }
};
const anotherWidget: Widget = {
  name: 'bar',
  foo: {
    b: 1,
  }
};

Playground

Samuel Goldenbaum
  • 18,391
  • 17
  • 66
  • 104
  • Does this answer your question? [Partial keys of union type as key of an object in typescript](https://stackoverflow.com/questions/64481968/partial-keys-of-union-type-as-key-of-an-object-in-typescript). You should use `foo: Partial>`. – Connor Low Dec 07 '21 at 22:18

1 Answers1

0

Use optional fields:

type Widget = {
  name: string,
  foo: { [key in Options]?: number }
}

Or Partial<T>:

type Widget = {
  name: string,
  foo: Partial<Record<Options, number>>
}

If you only accept one and only one option, check this answer for the full picture. This is the simple approach:

type OneKey<T extends string, V> = { [T1 in T]: Record<T1, V> }[T]
tokland
  • 66,169
  • 13
  • 144
  • 170