10

Type Definition for Enumeration Keys

Monday, November 23, 2020

Challenge: what is the proper type definition for an array of keys of an enumeration (enum)?

For example, let's say I have an enum and then declare a keys constant using Object.keys() on the enum:

enum Direction {
  Up,
  Down
}

const keys = Object.keys(Direction);

It seems that the inferred type using the TypeScript version 4.0.5 compiler is string[], which is close, but not exactly what I want.

Typeof Operator

You may already be familiar with the typeof operator in JavaScript. The operator returns a type string of the unevaluated operand. For example:

const user = {
  firstName: 'Brian'
  votes: 10
}

type a = typeof user.firstName; // 'string'

In the code above the typeof operator returns the string string, which is then assigned to a new a type. This type is inferred as a string as expected.

Keyof Type Operator

The keyof type operator returns a union type of all keys of a another type. Let's look an example:

interface User {
  firstName: string;
  votes: number;
}

type a = keyof User; // 'firstName' | 'votes'

The new a type is an indexed type union of the keys (properties) of the User interface. We could have manually defined the type as:

type a = 'firstName' | 'votes';

The potential problem occurs when we add a new property to our User interface. We would then need to update our a type accordingly.

Typeof and Keyof

Now, we can bring these two concepts together.

const user = {
  firstName: 'Brian',
  votes: 10
};

type a = keyof typeof user; // 'firstName' | 'votes'

Using both the keyof and typeof operators we can define a new a type that is an indexed type union of the keys (properties) of the user object.

Finally, we can use this same approach for type coercion of the keys of an enumeration.

Code Examples

strict type coercion

enum Direction {
  Up,
  Down
}

const keys = Object.keys(Direction) as Array<keyof typeof Direction>; // 'Up' | 'Down'

loose type inferencing

enum Direction {
  Up,
  Down
}

const keys = Object.keys(Direction); // string[]
Brian Love

I am a software engineer and Google Developer Expert in Web Technologies and Angular with a passion for learning, writing, speaking, teaching and mentoring. I regularly speaks at conferences and meetups around the country, and co-authored "Why Angular for the Enterprise" for O'Reilly. When not coding, I enjoy skiing, hiking, and being in the outdoors. I started lookout.dev to break down the barriers of learning in public. Learning in public fosters growth - for ourselves and others.

Google Developers Expert

Have a question or comment?