I'd like to get a string literal union from an enum.
For this enum…
enum Weekday {
MONDAY = 'mon',
TUESDAY = 'tue',
WEDNESDAY = 'wed'
}
… I'd like to get this:
type WeekdayType = 'mon' | 'tue' | 'wed';
I tried typeof keyof Weekday
but that resulted in 'MONDAY' | 'TUESDAY' | 'WEDNESDAY'
. Feel like the solution might have to do with mapped types but I can't seem to wrap my head around it.
How do I do this?
答案 0 :(得分:12)
这无法通过编程方式完成...您正在尝试将Weekday
类型Weekday.MONDAY | Weekday.TUESDAY | Weekday.WEDNESDAY
转换为WeekdayType
类型"mon" | "tue" | "wed"
。由于Weekday
是WeekdayType
的子类型,因此此转换是扩大的一种形式:
type WeekdayExtendsWeekdayType =
Weekday extends WeekdayType ? true : false
// type WeekdayExtendsWeekdayType = true
不幸的是,编译器没有给您提供从枚举类型中删除“枚举”性质并使您拥有普通文字类型的句柄。
那么,解决方法?也许您实际上并不需要enum
,但可以处理其属性值为字符串文字的对象:
const lit = <V extends keyof any>(v: V) => v;
const Weekday = {
MONDAY: lit("mon"),
TUESDAY: lit("tue"),
WEDNESDAY: lit("wed")
}
type Weekday = (typeof Weekday)[keyof typeof Weekday],
如果进行检查,则名为Weekday
的 value 的行为类似于枚举对象:
console.log(Weekday.TUESDAY); // tue
名为Weekday
的 type 的行为类似于您调用"mon" | "tue" | "wed"
的字符串值WeekdayType
的并集:
const w: Weekday = "wed"; // okay
const x: Weekday = "xed"; // error
因此,在此替代方法中,没有“枚举”性质,因此无需将类型Weekday
与类型WeekdayType
区分开。与实际的enum
(包括Weekday.MONDAY
之类的类型,您必须将其表示为笨重的typeof Weekday.MONDAY
或创建其他类型)有所不同别名),但它的行为可能也足够有用。这样对您有用吗?
希望有帮助。祝你好运!
答案 1 :(得分:3)
使用Typescript 4.1,可以做到!
enum Weekday {
MONDAY = 'mon',
TUESDAY = 'tue',
WEDNESDAY = 'wed'
}
type WeekdayType = `${Weekday}`;
注意:仅适用于字符串枚举值,不适用于数字枚举值。
答案 2 :(得分:0)
紧接着@jcalz答案和@ just-boris的评论,下面是一个带有const断言(打字稿3.4+)的示例:
const Weekday = {
MONDAY: "mon",
TUESDAY: "tue",
WEDNESDAY: "wed",
} as const;
type Weekday = (typeof Weekday)[keyof typeof Weekday],