From 1d0d5c6cffd489d86e8c13576656122ab84635ec Mon Sep 17 00:00:00 2001 From: Kir_Antipov Date: Fri, 20 Jan 2023 11:46:18 +0000 Subject: [PATCH] Made a function to retrieve enum keys --- src/utils/enum/enum-key.ts | 39 ++++++++++++++++++++++++++ tests/unit/utils/enum/enum-key.spec.ts | 38 +++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 src/utils/enum/enum-key.ts create mode 100644 tests/unit/utils/enum/enum-key.spec.ts diff --git a/src/utils/enum/enum-key.ts b/src/utils/enum/enum-key.ts new file mode 100644 index 0000000..a277951 --- /dev/null +++ b/src/utils/enum/enum-key.ts @@ -0,0 +1,39 @@ +import { isReadOnlyMap } from "@/utils/collections"; + +/** + * A type that represents the key of an enum type `T`. + * + * @template T - The enum type whose keys are being represented. + */ +export type EnumKey = keyof T extends string ? keyof T : never; + +/** + * Retrieves an array of the string keys of the specified `enum` object. + * + * @template T - Type of the enum. + * + * @param e - The enum object to retrieve the keys for. + * + * @returns An array of the string keys of the specified `enum` object. + */ +export function enumKeys(e: T): EnumKey[] { + if (isReadOnlyMap, unknown>(e)) { + return [...e.keys()]; + } + + return Object.getOwnPropertyNames(e).filter(key => isEnumKey(e, key)) as EnumKey[]; +} + +/** + * Determines if the provided key is an enumeration key. + * + * @template T - Type of the enum. + * + * @param e - The enum object to check the key against. + * @param key - The key to be checked. + * + * @returns `true` if the key is an enumeration key; otherwise, `false`. + */ +function isEnumKey(e: T, key: string): key is EnumKey { + return typeof e[key] !== "function" && key !== String(+key); +} diff --git a/tests/unit/utils/enum/enum-key.spec.ts b/tests/unit/utils/enum/enum-key.spec.ts new file mode 100644 index 0000000..e1d0465 --- /dev/null +++ b/tests/unit/utils/enum/enum-key.spec.ts @@ -0,0 +1,38 @@ +import { Enum } from "@/utils/enum/enum"; +import { enumKeys } from "@/utils/enum/enum-key"; + +describe("enumKeys", () => { + test("returns the correct keys for number-based built-in enums", () => { + enum NumberEnum { + A = 1, + B = 2, + C = 3, + } + + const keys = enumKeys(NumberEnum); + + expect(keys).toEqual(["A", "B", "C"]); + }); + + test("returns the correct keys for string-based built-in enums", () => { + enum StringEnum { + A = "a", + B = "b", + C = "c", + } + + const keys = enumKeys(StringEnum); + expect(keys).toEqual(["A", "B", "C"]); + }); + + test("returns the correct keys for custom enums created with Enum.create", () => { + const CustomEnum = Enum.create({ + A: 1n, + B: 2n, + C: 3n, + }); + + const keys = enumKeys(CustomEnum); + expect(keys).toEqual(["A", "B", "C"]); + }); +});