import type { Maybe, Nullable } from "./Maybe"; export type StrEnumType = { [K in T]: K; }; /** * Helper methods and properties for string enum types created with {@link strEnum}. * * Provides type-safe utilities for working with predefined string literal types, * including validation, comparison, and transformation operations. * * @template T - The union of string literals that make up this enum */ export type StrEnumHelpers = { /** Array of all valid enum values in declaration order */ values: T[]; /** Number of enum values */ length: number; /** * Synonym for {@link includes}. Checks if a string is a valid enum value. * @param s - String to check (can be null/undefined) * @returns Type predicate indicating if s is a valid enum value */ has(s: Nullable): s is T; /** * Type-safe check if a string is a valid enum value (case-sensitive). * @param s - String to check (can be null/undefined) * @returns Type predicate indicating if s is a valid enum value * @example * const Colors = strEnum("red", "green", "blue"); * Colors.includes("red") // true * Colors.includes("RED") // false */ includes(s: Nullable): s is T; /** * Get enum value with case-insensitive matching. * @param s - String to match (can be null/undefined) * @returns Matching enum value or undefined if no match * @example * const Colors = strEnum("red", "green", "blue"); * Colors.getCI("RED") // "red" * Colors.getCI("purple") // undefined */ getCI(s: Nullable): Maybe; /** * Create a new array containing only the specified enum values. * @param t - Enum values to include * @returns Array of specified enum values * @example * const Colors = strEnum("red", "green", "blue"); * Colors.pick("red", "blue") // ["red", "blue"] */ pick(...t: O[]): Extract[]; /** * Create a new array containing all enum values except the specified ones. * @param t - Enum values to exclude * @returns Array of remaining enum values * @example * const Colors = strEnum("red", "green", "blue"); * Colors.omit("green") // ["red", "blue"] */ omit(...t: O[]): Exclude[]; /** * Get the zero-based index of an enum value. * @param s - Enum value to find (can be null/undefined) * @returns Index of the value or undefined if not found * @example * const Colors = strEnum("red", "green", "blue"); * Colors.indexOf("green") // 1 * Colors.indexOf("purple") // undefined */ indexOf(s: Nullable): Maybe; /** * Get the ordinal position of an enum value, or length if not found. * Useful for sorting where invalid values should sort last. * @param s - Enum value to find (can be null/undefined) * @returns Index of the value, or enum length if not found * @example * const Colors = strEnum("red", "green", "blue"); * Colors.ordinal("green") // 1 * Colors.ordinal("purple") // 3 (length) */ ordinal(s: Nullable): number; /** * Synonym for {@link getCI}. Get enum value with case-insensitive matching. * @param s - String to validate (can be null/undefined) * @returns Valid enum value or undefined if no match */ toValid(s: Nullable): Maybe; /** * Find the first valid enum value from a list of candidates. * @param arr - Array of potential enum values to check * @returns First valid enum value found, or undefined if none match * @example * const Colors = strEnum("red", "green", "blue"); * Colors.firstValid("purple", "GREEN", "red") // "green" (case-insensitive match) */ firstValid(...arr: Nullable[]): Maybe; /** * Apply a function to a string if it's a valid enum value. * @param s - String to check and potentially transform * @param f - Function to apply if s is a valid enum value * @returns Result of function application, or undefined if s is invalid * @example * const Colors = strEnum("red", "green", "blue"); * Colors.mapValid("red", color => color.toUpperCase()) // "RED" * Colors.mapValid("purple", color => color.toUpperCase()) // undefined */ mapValid(s: Nullable, f: (t: T) => R): Maybe; /** * Compare two strings based on their enum order. * @param a - First string to compare * @param b - Second string to compare * @returns -1 if a < b, 0 if a === b, 1 if a > b, undefined if either is invalid * @example * const Colors = strEnum("red", "green", "blue"); * Colors.cmp("red", "green") // -1 (red comes before green) * Colors.cmp("blue", "red") // 1 (blue comes after red) */ cmp(a: Nullable, b: Nullable): Maybe; /** * Check if first enum value comes before second in declaration order. * @param a - First enum value * @param b - Second enum value * @returns True if a comes before b in the enum declaration * @example * const Colors = strEnum("red", "green", "blue"); * Colors.lt("red", "green") // true * Colors.lt("green", "red") // false */ lt(a: T, b: T): boolean; /** * Get the next enum value in declaration order. * @param s - Current enum value * @returns Next enum value, or undefined if s is the last value or invalid * @example * const Colors = strEnum("red", "green", "blue"); * Colors.next("red") // "green" * Colors.next("blue") // undefined (no next value) */ next(s: Nullable): Maybe; /** * Create a new StrEnum with the values in reverse order. * * (This follows the new "toReversed" ES2023 naming convention for methods that return a new object) * @returns New StrEnum with values in reverse declaration order * @example * const Colors = strEnum("red", "green", "blue"); * const Reversed = Colors.toReversed(); * Reversed.values // ["blue", "green", "red"] */ toReversed(): StrEnum; /** * Makes the StrEnum iterable, allowing use in for...of loops and array destructuring. * @returns Iterator that yields enum values in declaration order * @example * const Colors = strEnum("red", "green", "blue"); * for (const color of Colors) { * console.log(color); // "red", "green", "blue" * } * const [first, second] = Colors; // first="red", second="green" */ [Symbol.iterator](): IterableIterator; /** * String tag used by Object.prototype.toString() for better debugging. * @example * const Colors = strEnum("red", "green", "blue"); * Object.prototype.toString.call(Colors) // "[object StrEnum]" */ [Symbol.toStringTag]: "StrEnum"; }; export type StrEnum = StrEnumType & StrEnumHelpers; export type StrEnumKeys = Type extends StrEnum ? X : never; export declare function strEnum(...o: T[]): StrEnum;