TypeScript Enum Utility Functions
Enums are a powerful feature in TypeScript for defining a set of named constants. However, they can sometimes be cumbersome to work with directly, especially when you need to iterate over their values, get a list of keys, or perform other common operations. This challenge asks you to create a set of utility functions that enhance the usability of TypeScript enums.
Problem Description
Your task is to implement several utility functions that operate on TypeScript enums. These functions should provide common functionalities that are not directly supported by the native enum object in JavaScript. Specifically, you need to create functions to:
- Get all values of an enum: Return an array containing all the numeric or string values defined in an enum.
- Get all keys (names) of an enum: Return an array containing all the string keys (names) of the enum members.
- Get a specific value by its key: Given an enum key, return its corresponding value.
- Get a specific key by its value: Given an enum value, return its corresponding key.
You should aim for type safety and handle both numeric and string enums.
Examples
Example 1: Numeric Enum
enum Direction {
Up,
Down,
Left,
Right,
}
// Assuming you have implemented the utility functions:
// Get all values
const allDirectionValues = getAllEnumValues(Direction);
console.log(allDirectionValues);
// Expected Output: [0, 1, 2, 3]
// Get all keys
const allDirectionKeys = getAllEnumKeys(Direction);
console.log(allDirectionKeys);
// Expected Output: ["Up", "Down", "Left", "Right"]
// Get value by key
const upValue = getValueByKey(Direction, "Up");
console.log(upValue);
// Expected Output: 0
// Get key by value
const leftKey = getKeyByValue(Direction, 2);
console.log(leftKey);
// Expected Output: "Left"
Example 2: String Enum
enum Status {
Pending = "PENDING",
Processing = "PROCESSING",
Completed = "COMPLETED",
Failed = "FAILED",
}
// Assuming you have implemented the utility functions:
// Get all values
const allStatusValues = getAllEnumValues(Status);
console.log(allStatusValues);
// Expected Output: ["PENDING", "PROCESSING", "COMPLETED", "FAILED"]
// Get all keys
const allStatusKeys = getAllEnumKeys(Status);
console.log(allStatusKeys);
// Expected Output: ["Pending", "Processing", "Completed", "Failed"]
// Get value by key
const processingValue = getValueByKey(Status, "Processing");
console.log(processingValue);
// Expected Output: "PROCESSING"
// Get key by value
const failedKey = getKeyByValue(Status, "FAILED");
console.log(failedKey);
// Expected Output: "Failed"
Example 3: Mixed Enum (for getKeyByValue and getValueByKey)
TypeScript allows for mixed enums (numeric and string values). Your functions should ideally handle these, but the primary focus is on standard numeric or string enums. For simplicity in implementation, you might assume standard enums where all members are either numeric or string. If a key/value pair doesn't exist, the functions should handle this gracefully (e.g., return undefined).
enum MixedEnum {
A,
B = "B_VALUE",
C, // This will be numeric: 2
}
// Get value by key
const aValue = getValueByKey(MixedEnum, "A"); // 0
const bValue = getValueByKey(MixedEnum, "B"); // "B_VALUE"
const cValue = getValueByKey(MixedEnum, "C"); // 2
// Get key by value
const keyFor0 = getKeyByValue(MixedEnum, 0); // "A"
const keyForBValue = getKeyByValue(MixedEnum, "B_VALUE"); // "B"
const keyFor2 = getKeyByValue(MixedEnum, 2); // "C"
Constraints
- Language: TypeScript.
- Generics: Utilize generics to make the utility functions type-safe and reusable across different enums.
- Return Types: Ensure precise return types for each function. For example,
getKeyByValueshould returnstring | undefined. - Enum Types: The functions should work correctly for both numeric and string enums.
- Efficiency: While not a strict performance bottleneck for typical enum sizes, avoid unnecessarily inefficient operations.
Notes
- TypeScript enums compile to JavaScript objects at runtime. Numeric enums in JavaScript also create reverse mappings (value to key). String enums do not. Your utility functions should abstract away these differences.
- When dealing with numeric enums, be aware that JavaScript creates reverse mappings. For example,
Direction[0]would yield"Up". Your functions should correctly interpret and utilize these runtime representations. - Consider how your functions should behave if an invalid key or value is provided (e.g., a key that doesn't exist in the enum, or a value that doesn't correspond to any key). Returning
undefinedis a common and acceptable approach. - For
getAllEnumValues, if you have a mixed enum, you might need to decide how to represent the values (e.g., as an array ofstring | number). For simplicity, you could focus on standard numeric or string enums. - The
getKeyByValuefunction will need to iterate through both the forward (key -> value) and potentially the reverse (value -> key) mappings of the enum object to find a match.