How to get enum size as a type in Typescript

Viewed 169

In Typescript there is a way to get the size of the array or tuple and use it as a type:

type Tuple = [number, string, boolean];
type Arr = [0, 1, 2];

type LengthOf<T extends any[]> = T["length"];

type Test = LengthOf<Tuple>; // 3
type Test2 = LengthOf<Arr>; // 3

Is there any way to do the same thing (extract the length/size) with enums? Enum example:

enum Example {
  how = "how",
  to = "to",
  count = "count",
  enum = "enum",
  entries = "entries"
}

And just to be clear, I'm interested in getting this as a type NOT a value. I know about Object.keys(Example).length.

1 Answers

It is doable:

enum Example {
  how = "how",
  to = "to",
  count = "count",
  enum = "enum",
  entries = "entries"
}
// credits goes to https://stackoverflow.com/a/50375286
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
  k: infer I
) => void
  ? I
  : never;

// credits goes to https://github.com/microsoft/TypeScript/issues/13298#issuecomment-468114901
type UnionToOvlds<U> = UnionToIntersection<
  U extends any ? (f: U) => void : never
>;

type PopUnion<U> = UnionToOvlds<U> extends (a: infer A) => void ? A : never;

type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : true;

type UnionToArray<T, A extends unknown[] = []> = IsUnion<T> extends true
  ? UnionToArray<Exclude<T, PopUnion<T>>, [PopUnion<T>, ...A]>
  : [T, ...A];


type Result = UnionToArray<keyof typeof Example>['length']

More info you can find in my blog and in this gist

Related