簡體   English   中英

打字稿:來自枚舉的字符串文字聯合類型

[英]Typescript: string literal union type from enum

我想從枚舉中獲取字符串文字聯合。

對於這個枚舉…

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

......我想得到這個:

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

我試過typeof keyof Weekday但結果是'MONDAY' | 'TUESDAY' | 'WEDNESDAY' 'MONDAY' | 'TUESDAY' | 'WEDNESDAY' 'MONDAY' | 'TUESDAY' | 'WEDNESDAY' 感覺解決方案可能與映射類型有關,但我似乎無法理解它。

我該怎么做呢?

TS4.1 答案

type WeekdayType = `${Weekday}`;

PRE TS-4.1 答案:

這不能以編程方式完成...您正在嘗試轉換類型Weekday ,即Weekday.MONDAY | Weekday.TUESDAY | Weekday.WEDNESDAY Weekday.MONDAY | Weekday.TUESDAY | Weekday.WEDNESDAY Weekday.MONDAY | Weekday.TUESDAY | Weekday.WEDNESDAY ,到類型WeekdayType"mon" | "tue" | "wed" "mon" | "tue" | "wed" "mon" | "tue" | "wed" 這種轉換是一種擴大形式,因為WeekdayWeekdayType的子類型:

type WeekdayExtendsWeekdayType = 
  Weekday extends WeekdayType ? true : false
// type WeekdayExtendsWeekdayType = true

不幸的是,編譯器沒有為您提供從 enum 類型中刪除“enum”-ness 並為您留下純文字類型的句柄。


那么,解決方法? 也許您實際上並不需要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" "mon" | "tue" | "wed" 您正在調用WeekdayType "mon" | "tue" | "wed"

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

因此,在此解決方法中,沒有“枚舉”特性,因此無需區分Weekday類型和WeekdayType類型。 它與實際的enum (包括Weekday.MONDAY類的類型,您必須將其表示為麻煩的typeof Weekday.MONDAY或為其創建不同的類型別名)略有不同,但它的行為可能足夠相似以供使用. 那對你有用嗎?

希望有幫助。 祝你好運!

打字稿 4.1+:

如前所述,這可以通過使用模板文字類型來實現,如下所示:

type WeekdayType = `${Weekday}`;

打字稿 3.4+:

跟進@jcalz 的回答和@just-boris 的評論,這是一個帶有 const 斷言的示例:

const Weekday = {
  MONDAY: "mon",
  TUESDAY: "tue",
  WEDNESDAY: "wed",
} as const;

type Weekday = (typeof Weekday)[keyof typeof Weekday];

編輯:

為那些想要深入挖掘的人寫了一篇博文

使用Typescript 4.1可以做到!

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

type WeekdayType = `${Weekday}`;

警告:這僅適用於字符串枚舉值,不適用於數字枚舉值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM