Skip to content

isEnumValue function ​

Checks whether a value is one of the values of an enum, in O(1): the values of each enum are read once.

Cache

The values of each enum, in a WeakMap: nothing is kept once the enum is unused.

ts
import { isEnumValue } from 'utils';

Signature ​

ts
export function isEnumValue<E extends EnumObject>(enumObject: E, value: unknown): value is E[keyof E]

Parameters ​

NameDescription
EThe type of the enum object.
enumObjectThe enum to search, such as Direction.
valueThe value to look for.

Returns ​

true when the value is one of the enum's values.

Example ​

ts
enum Direction { Up, Down }
isEnumValue(Direction, 0); // true
isEnumValue(Direction, 'Up'); // false (a name, not a value)

Tests ​

Line coverage: 100 %.

  • ✅ accepts the values of a numeric enum, not its names
  • ✅ accepts the values of a string enum, not its keys
  • ✅ handles numeric enums with explicit values
  • ✅ handles const objects used as enums

Source ​

src/enum/is-enum-value.ts (on GitHub)

Uses ​

  • EnumObject: Any TypeScript enum, or a const object used as one.
  • getEnumValues: Lists the values of an enum, without the names of the reverse mapping of numeric enums.

Used by ​

  • toEnumValue: Returns a value typed as an enum member: the value itself when it belongs to the enum, the fallback otherwise.

Files it needs ​

src/enum/is-enum-value.ts imports, directly or not:

Source code
ts
import type { EnumObject } from './enum-object';
import { getEnumValues } from './get-enum-values';

const valuesByEnum = new WeakMap<object, ReadonlySet<unknown>>();

/**
 * Checks whether a value is one of the values of an enum, in O(1): the values of each enum are read once.
 *
 * @template E - The type of the enum object.
 * @param enumObject - The enum to search, such as `Direction`.
 * @param value - The value to look for.
 * @returns `true` when the value is one of the enum's values.
 * @cached The values of each enum, in a `WeakMap`: nothing is kept once the enum is unused.
 * @example
 * enum Direction { Up, Down }
 * isEnumValue(Direction, 0); // true
 * isEnumValue(Direction, 'Up'); // false (a name, not a value)
 */
export function isEnumValue<E extends EnumObject>(enumObject: E, value: unknown): value is E[keyof E] {
  let values = valuesByEnum.get(enumObject);
  if (!values) {
    values = new Set(getEnumValues(enumObject));
    valuesByEnum.set(enumObject, values);
  }
  return values.has(value);
}
Test file
ts
import { isEnumValue } from './is-enum-value';

enum Direction {
  Up = 0,
  Down = 1,
}

enum Color {
  Red = 'red',
  Green = 'green',
}

enum Sparse {
  Low = 1,
  High = 10,
}

describe(isEnumValue, () => {
  it('accepts the values of a numeric enum, not its names', () => {
    expect(isEnumValue(Direction, 0)).toBe(true);
    expect(isEnumValue(Direction, Direction.Down)).toBe(true);
    expect(isEnumValue(Direction, 'Up')).toBe(false);
    expect(isEnumValue(Direction, '0')).toBe(false);
    expect(isEnumValue(Direction, 2)).toBe(false);
  });

  it('accepts the values of a string enum, not its keys', () => {
    expect(isEnumValue(Color, 'red')).toBe(true);
    expect(isEnumValue(Color, 'Red')).toBe(false);
    expect(isEnumValue(Color, undefined)).toBe(false);
  });

  it('handles numeric enums with explicit values', () => {
    expect(isEnumValue(Sparse, 10)).toBe(true);
    expect(isEnumValue(Sparse, 'High')).toBe(false);
    expect(isEnumValue(Sparse, 5)).toBe(false);
  });

  it('handles const objects used as enums', () => {
    const status = { idle: 'idle', running: 'running' } as const;
    expect(isEnumValue(status, 'running')).toBe(true);
    expect(isEnumValue(status, 'stopped')).toBe(false);
  });
});

Keywords: is, enum, value, enums, function

Generated from the JSDoc of the sources.