From enum:
enum Weekdays {
Monday = 1,
Tuesday = 2
}
We would like to get this type:
type WeekdaysType = 1 | 2
If, instead of the numeric enum, you create a const object whose prototypes correspond to the numeric values your original enum had:
const Weekdays = {
Monday: 1,
Tuesday: 2,
} as const;
Then, you can define a type with the same name as the object above:
type Weekdays = (typeof Weekdays)[keyof typeof Weekdays];
This type is the union of the types of the object properties, i.e., 1 | 2. That's why you need the as const assertion above so that TypeScript infers the literal types 1 and 2 for Monday and Tuesday, respectively. Otherwise, it would infer the broader type number and the type Weekdays would result in number as a consequence.
Both typeofs aren't JavaScript's typeof despite taking a value (i.e., the const object) as their operand. They correspond to TypeScript's typeof because they are being used in the type space (they are inside a type definition):
type Weekdays = (typeof Weekdays)[keyof typeof Weekdays];
^^^^^^ ^^^^^^
Finally, note that in this solution, you have both a type and a value with the name Weekdays: the type Weekdays and the const object Weekdays. There are no clashing issues here since they live in different spaces: the type and value spaces.
With TypeScript 4.1+, you can use template literal types:
enum Weekdays {
Monday = 1,
Tuesday = 2,
};
type WeekdaysType = `${Weekdays}`;
Caveat: This only works with enums that have string values, so for your particular use case, WeekdaysType would be "1" | "2", rather than 1 | 2. As far as I'm aware, there's no current way to dynamically extract numeric enum values into a union type.
type WeekdaysType = "1" | "2"enum Code {
a = 111,
b = 222,
c = 'abc'
}
type StrToNum<Str> =
Str extends `${infer Num extends number}`
? Num
: Str
type res = StrToNum<`${Code}`>;
type res = number | "abc" what I would like to have is type res = 111 | 222 | "abc".const Weekdays {
Monday: 1,
Tuesday: 2,
} as const;
type Union<T> = T[keyof T];
type WeekdaysType = Union<typeof Weekdays>; // type WeekdaysType = 1 | 2
// you can use like enum
console.log(Weekdays.Monday) // 1
enum ZeroOrOne {
Zero = 0,
One = 1
}
const zeroOrOne: ZeroOrOne = 2; // no error!!
Weekdaysitself is that union.enumyou probably don't want anenum. Why not change it toconst Weekdays = {Monday: 1, Tuesday: 2} as const; type WeekDays = (typeof Weekdays)[keyof typeof Weekdays]like this? What is the use case here?