With Tenum<T>, TypeScript can automatically infer strict, type-safe values,
eliminating the need for manual type guards. This ensures that only valid
values can be assigned, preventing runtime errors.
Traditional TypeScript enums have weak type enforcement and require type guards to validate values at runtime. This makes them unreliable for ensuring strict type safety.
enum ColorEnum {
RED = 'red',
GREEN = 'green',
BLUE = 'blue',
}
// TypeScript allows invalid values
const color: ColorEnum = 'yellow' as ColorEnum // No type error, but incorrect
// Requires a manual type guard
function isValidColorEnum(value: unknown): value is ColorEnum {
return Object.values(ColorEnum).includes(value as ColorEnum)
}
function handleColor(color: ColorEnum): string {
if (!isValidColorEnum(color)) {
return 'Invalid color'
}
return `Selected color: ${color}`
}
console.log(handleColor('yellow' as any)) // Requires a runtime check- TypeScript does not prevent invalid values at compile-time.
- Requires manual type guards (isValidColorEnum) to validate values.
- Runtime validation is needed, making the code less safe and performant.
With Tenums, TypeScript enforces correctness at compile-time, ensuring that only valid values are used. Invalid values are caught before the code runs.
const Colors = {
RED: 'red',
GREEN: 'green',
BLUE: 'blue',
} as const
// Automatically infers "red" | "green" | "blue"
type ColorsType = Tenum<typeof Colors>
function handleColor(color: ColorsType) {
return `Selected color: ${color}`
}
// Works because "red" is a valid value
console.log(handleColor(Colors.RED)) // "red"
// Compile-time error: Argument of type '"yellow"' is not assignable to parameter of type '"red" | "green" | "blue"'.
console.log(handleColor('yellow'))- Strict type inference:
"red" | "green" | "blue"instead of juststring. - No runtime validation required—TypeScript enforces correctness at compile-time.
- Eliminates type guards—invalid values fail before execution.
- Extracts the strict union of values from an object.
const StatusCodes = {
OK: 200,
NOT_FOUND: 404,
SERVER_ERROR: 500,
} as const
type StatusType = Tenum<typeof StatusCodes>
// Works
const status: StatusType = 200
// Compile-time error: "400" is not assignable to "200 | 404 | 500"
const badStatus: StatusType = 400TenumKeys<T> Extracts the union of keys from an object while ensuring
immutability.
export type TenumKeys<T extends Record<string, unknown>> = keyof Readonly<T>Example Usage:
const Colors = {
RED: 'red',
GREEN: 'green',
BLUE: 'blue',
} as const
type ColorKeys = TenumKeys<typeof Colors> // "RED" | "GREEN" | "BLUE"