如何在 TypeScript 中将联合类型转换为枚举?

33

我希望将联合类型转换为 TypeScript 中的枚举,或者类似于枚举的东西。

这让我感到很困惑。

谢谢您阅读我的问题。

type status = 'start' | 'loading' | 'stop';

class Loading {
    static staticStatus: status;
}
Loading.staticStatus.start; // i want to use.
或者
type status = 'start' | 'loading' | 'stop';

enum statusEnum = ?????;

class Loading {
    static staticStatus = statusEnum;
}
Loading.staticStatus.start; // i want to use.

抱歉我没有详细地写出我的问题。


const schema ={
 status: Joi.string()
        .required()
        .valid(
            'start',
            'loading',
            'stop',
        )
}

// type setStatusType =  'start' | 'loading' | 'stop' is like this
type setStatusType = PickType<Joi.extractType<typeof schema>, 'status'>; 

enum statusEnum = ?????;

class Loading {
    static staticStatus = statusEnum;

    public setLoading() {
    this.status = Loading.staticStatus.loading // I want to use this.
    }
}

所以我想将联合类型转换为枚举...


1
必须有联合类型。很抱歉我没有详细说明我的问题。 - bugtype kr
我正在使用一个自动生成联合类型的库,而不是枚举,但拥有枚举将非常有用。那些说“只需用另一种方式做”解决方案并不特别有用。 - Hawxby
1
我有同样的问题(自动生成的“类型”),但实际上没有答案解决这个问题。 - tyteen4a03
4个回答

33

不确定如何从Union获取enum,但如果需要两者,您可以很容易地进行反向操作。


enum Status {
 start,
 loading,
 stop
}

type StatusAsUnion = keyof typeof Status

希望这对您有所帮助


0
枚举类型使用enum关键字进行定义,如下所示:

使用 TypeScript 枚举编写易读的代码

enum Continents {
    North_America,
    South_America,
    Africa,
    Asia,
    Europe,
    Antartica,
    Australia
}

// usage
var region = Continents.Africa;

TypeScript枚举类型

有三种类型的TypeScript枚举:

  1. 数字枚举
  2. 字符串枚举
  3. 异构枚举

数字枚举 默认情况下,TypeScript枚举是基于数字的。这意味着它们可以将字符串值存储为数字。可以将数字和与其兼容的任何其他类型分配给枚举实例。假设我们想要存储周末的天数。在TypeScript中表示枚举可能如下所示:

enum Weekend {
  Friday,
  Saturday,
  Sunday
}

在上面的代码块中,我们有一个称为Weekend的枚举。该枚举有三个值,分别是:Friday,Saturday和Sunday。在TypeScript中,就像在其他一些语言中一样,枚举值从零开始,每个成员增加一。它们将被存储如下:
Friday = 0
Saturday = 1
Sunday = 2

我们可以看到,枚举类型始终被分配数字以进行存储,该值始终采用数字零的值,尽管我们可以使用自己的逻辑自定义存储值。 自定义数字枚举 在TypeScript中,我们可以指定枚举类型的第一个数字值。使用上面的周末示例,我们可以这样初始化第一个数字值:
enum Weekend {
  Friday = 1,
  Saturday,
  Sunday
}

上面的代码块将星期五存储为1,星期六存储为2,星期日存储为3。如果我们给第一个成员添加一个数字,那么其余成员仍然会顺序递增1。但是,我们有权利决定不想要连续的递增,可以给它们任何数值。下面的代码块是语义化的,并且在TypeScript中有效:
enum Weekend {
  Friday = 1,
  Saturday = 13,
  Sunday = 5
}

就像 TypeScript 中的其他数据类型一样,我们可以将枚举用作函数参数或返回类型,如下所示:

前端应用程序监控,识别、修复、跟踪。获取免费试用 >

enum Weekend {
  Friday = 1,
  Saturday,
  Sunday
}

function getDate(Day: string): Weekend {
    if ( Day === 'TGIF') {
        return Weekend.Friday;
    }
 }

let DayType: Weekend = getDate('TGIF');

在上面的代码块中,我们声明了一个Weekend枚举。然后我们声明了一个getDate函数,该函数接受输入的Day并返回一个Weekend枚举。在函数中,我们检查一些条件,现在返回一个枚举成员。 字符串枚举 到目前为止,我们只看过成员值为数字的枚举。在TypeScript中,您的枚举成员也可以是字符串值。由于它们具有有意义的字符串值,因此字符串枚举对于错误日志记录和调试非常重要且易于处理。
enum Weekend {
  Friday = 'FRIDAY',
  Saturday = 'SATURDAY',
  Sunday = 'SUNDAY'
}

它可以用于像这样的条件语句中比较字符串:
enum Weekend {
  Friday = 'FRIDAY',
  Saturday = 'SATURDAY',
  Sunday ='SUNDAY'
}

const value = someString as Weekend;
if (value === Weekend.Friday || value === Weekend.Sunday){
    console.log('You choose a weekend');
    console.log(value); 
}

在上面的例子中,我们定义了一个字符串枚举Weekend,就像我们之前定义的数字枚举一样,但这次是用字符串作为枚举值。数字枚举和字符串枚举之间的显然区别是,数字枚举值通常会自动递增,而字符串枚举值不会递增,每个值都是独立初始化的。
异构枚举 TypeScript 还允许混合使用字符串和数字,称为异构枚举值:
enum Weekend {
  Friday = 'FRIDAY',
  Saturday = 1,
  Sunday = 2
}

尽管这是可能的,但需要使用此用例的场景范围非常小。因此,除非您真的想以聪明的方式利用JavaScript的运行时行为,否则建议不要使用异构枚举。
计算枚举 数字枚举的值可以是常量或可评估值,就像TypeScript中的任何其他数字数据类型一样。您可以使用计算值定义或初始化数字枚举:
enum Weekend {
  Friday = 1,
  Saturday = getDate('TGIF'),
  Sunday = Saturday * 40
}

function getDate(day : string): number {
    if (day === 'TGIF') {
        return 3;
    }
}
Weekend.Saturday; // returns 3
Weekend.Sunday; // returns 120

当枚举包含计算和常量成员时,未初始化的枚举成员要么排在首位,要么必须在具有数字常量的其他已初始化成员之后。忽略此规则会导致初始化错误-如果您看到这个错误,请记得重新排列枚举成员。
常量枚举 如果您想提高数字枚举的性能,可以将它们声明为常量。让我们使用周末的例子来说明:
enum Weekend {
  Friday = 1,
  Saturday,
  Sunday
}

var day = Weekend.Saturday;

当编译为 JavaScript 时,在执行时运行时会查找 Weekend 并查找 Weekend.Saturday。为了在运行时获得最佳性能,您可以将枚举设置为常量,如下所示:

const enum Weekend {
  Friday = 1,
  Saturday,
  Sunday
}
var day = Weekend.Saturday;

编译时生成的带有常量的 JavaScript 如下所示:
var day = 2;

我们可以看到编译器仅内联了枚举的使用,并在看到const时不必生成枚举声明的JavaScript。当您需要进行数字转字符串或字符串转数字查找的用例时,了解这种选择及其后果非常重要。您还可以传递编译器标志--preserveConstEnums,它仍将生成Weekenddefinition。
反向映射 TypeScript枚举支持反向映射,这意味着我们不仅可以访问枚举成员的值,还可以访问枚举名称本身。下面使用我们第一个演示的示例来描绘这一点:
enum Weekend {
  Friday = 1,
  Saturday,
  Sunday
}
Weekend.Saturday     
Weekend["Saturday"];  
Weekend[2];

在上面的代码块中,Weekend.Saturday将返回2,然后Weekend["Saturday"]也将返回2,但有趣的是,由于反向映射,Weekend[2]将返回其成员名称Saturday。这是由于反向映射。我们可以通过日志命令看到TypeScript解释反向映射的简单方法:
enum Weekend {
  Friday = 1,
  Saturday,
  Sunday
}
console.log(Weekend);

如果您在控制台中运行此命令,您将看到以下输出:
{
  '1': 'Friday',
  '2': 'Saturday',
  '3': 'Sunday',
  Friday   : 1,
  Saturday : 2,
  Sunday  : 3
}

对象包含枚举,既作为值又作为名称,这正是TypeScript所期望的反向映射的优势所在。
何时使用TypeScript枚举: 有些场景和适当的用例非常适合使用枚举,这样可以达到最佳效果并提高效率。
枚举可以像其他TypeScript数据类型一样在数组初始化中使用。
以下是一个快速示例:
enum NigerianLanguage {
  Igbo,
  Hause, 
  Yoruba
}

//can be used in array initialisation 
let citizen = {
  Name: 'Ugwunna',
  Age: 75,
  Language: NigerianLanguage.Igbo
}

枚举类型应该在有明确常量值的情况下使用,比如一周七天:

enum Days {
  Sunday = 1,
  Monday,
  Tuesday,
  Wednesday,
  Thursday,
  Friday,
  Saturday
}

枚举也可以用于需要在变量中表示字符串或常量的地方。


0

在我的情况下,我使用next

import { IExternal } from 'external';

enum Types = {
   FIRST = 'first',
   SECOND = 'second'
}

interface IInternal extends Pick<IExternal, 'types'> {
    types: Types
}

IExternal['types'] === 'first' | 'second' | 'something' | 'else';

IInternal['types'] === 'first' | 'second'; and compatible with IExternal['types']

它允许您将联合类型用作枚举值,并提供兼容性检查。


-3

最简单的解决方案是使用 string enum

enum Status {
    start = 'start',
    loading = 'loading',
    stop = 'stop'
}


class Loading {
    static staticStatus: Status;
}

Loading.staticStatus = Status.loading;

更多

字符串枚举


1
是的,一旦你决定使用枚举,你就必须在所有地方引用该枚举。 例如 Loading.staticStatus = 'loading' 将导致类型检查错误。 - duhseekoh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接