Typescript:来自枚举的字符串文字联合类型

问题描述 投票:5回答:1

我想从枚举中得到一个字符串文字联合。

对于这个枚举......

enum Weekday {
    MONDAY = 'mon',
    TUESDAY = 'tue',
    WEDNESDAY = 'wed'
}

......我想得到这个:

type WeekdayType = 'mon' | 'tue' | 'wed';

我尝试了typeof keyof Weekday,但结果导致'MONDAY' | 'TUESDAY' | 'WEDNESDAY'。感觉解决方案可能与映射类型有关,但我似乎无法绕过它。

我该怎么做呢?

typescript enums
1个回答
12
投票

这不能以编程方式完成...你试图将类型WeekdayWeekday.MONDAY | Weekday.TUESDAY | Weekday.WEDNESDAY)转换为类型WeekdayType,即"mon" | "tue" | "wed"。这种转换是一种扩大的形式,因为WeekdayWeekdayType的子类型:

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的值的行为类似于枚举对象:

console.log(Weekday.TUESDAY); // tue

而名为Weekday的类型就像你调用"mon" | "tue" | "wed"的字符串值WeekdayType的联合一样:

const w: Weekday = "wed"; // okay
const x: Weekday = "xed"; // error

所以在这种解决方法中,没有“枚举”性,因此无需将类型WeekdayWeekdayType类型区分开来。它与实际的enum(包括像Weekday.MONDAY这样的类型,你必须表示为繁琐的typeof Weekday.MONDAY或为它创建不同的类型别名)有点不同,但它可能表现得足够相似而且非常有用。那对你有用吗?

希望有所帮助。祝好运!

© www.soinside.com 2019 - 2024. All rights reserved.