1

I have an interface:

interface Example {
  foo: boolean
  bar: boolean
}

And I'd like a type that matches ['foo', 'bar']

I've tried

type Keys = (keyof Example)[]

This matches an empty array, as it doesn't require all of the keys, just partial.

Is there a way to do this?

If this isn't possible? Is it possible to require a type to have all items in the array?

const shouldFail = ['foo']
const shouldPass = ['foo', 'bar']
ThomasReggi
  • 55,053
  • 85
  • 237
  • 424

1 Answers1

1

See the question that Jared mentioned.

If control over the order of the keys matters in the array, it is better to define the array and derive the shape of your interface from the array:

TS Playground

const exampleKeys = ['foo', 'bar'] as const;
type ExampleKeys = typeof exampleKeys; // the type you want

type ExampleKey = ExampleKeys[number];
type Example = Record<ExampleKey, boolean>;

const example: Example = {
  foo: true,
  bar: false,
};

Using this technique also solves a frequent problem: iterating objects in a type-safe way:

for (const key in example) {
  const bool = example[key]; /*
               ^^^^^^^^^^^^
  Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Example'.
  No index signature with a parameter of type 'string' was found on type 'Example'.(7053) */
}

for (const key of exampleKeys) {
  const bool = example[key];
}
jsejcksn
  • 27,667
  • 4
  • 38
  • 62