【问题标题】:Check if function argument is a specific type of enum in typescript检查函数参数是否是打字稿中特定类型的枚举
【发布时间】:2020-09-02 22:38:00
【问题描述】:

我有一个函数,它接受一个参数,该参数在打字稿中有几个不同的枚举类型。我想检查参数具有哪种枚举类型。甚至可以检查吗?这是一个示例代码:

enum X {
    ONE,
    TWO
}

enum Y {
    THREE,
    FOUR
}

function check(arg1: X | Y) {
    if (arg1 is X) {
        // do something with X
    }
    if (arg1 is Y) {
        // do something with Y
    }
}

【问题讨论】:

    标签: typescript enums


    【解决方案1】:

    当您使用枚举类型(例如,let value: X = X.ONE)描述变量时,该变量需要枚举属性之一的值,而不是枚举本身。枚举的主要思想是记录和重用一组值(例如,enum Colors {BLUE: '#0000ff', YELLOW: '#ffff00'})。因此,如果您使用 Colors 枚举描述变量,则该变量将接受 Colors.BLUE 或 Colors.YELLOW 解析为颜色的实际值(例如,'#0000ff');这样该变量将无法保存 Colors 枚举本身,而只能保存枚举的值。

    枚举作为对象保留在编译代码中。例如,示例中的枚举 X 和 Y 变成以下对象:

    var X = { '0': 'ONE', '1': 'TWO', ONE: 0, TWO: 1 }
    var Y = { '0': 'THREE', '1': 'FOUR', THREE: 0, FOUR: 1 }
    

    在您的函数中,arg1 将包含这些枚举之一的值,即 0 或 1。因此,在您的示例中,您将能够检查 arg1 是否属于这些对象之一(例如,X[arg1] !== undefined),但您将无法保证 arg1 仅属于 X 或仅属于 Y,因为 X 和 Y 在某些时候可能包含相同的键和/或值(例如,两者都将具有键“一”)。

    因此,我们需要根据价值比较做出决策,如下所示:

    if (arg1 === X.ONE) {
      // do something
    }
    
    if (arg2 === Y.THREE) {
      // do something
    }
    

    或者通过检查一个值是否属于一个特定的枚举对象:

    if (X[arg1] !== undefined) {
      // do something
    }
    
    if (Y[arg1] !== undefined) {
      // do something
    }
    

    没有 TS 功能可以检查值是否仅属于特定枚举。

    【讨论】:

      【解决方案2】:

      你可以使用枚举类型保护函数

      Generic enum type guard

      在这种情况下:

      enum X {
          ONE,
          TWO
      }
      
      enum Y {
          THREE = 3,
          FOUR
      }
      
      const isSomeEnum = <T>(e: T) => (token: any): token is T[keyof T] =>
          (Object as any).values(e).includes(token as T[keyof T]);
      
      function check(arg1: X | Y) {
          if (isSomeEnum(X)(arg1)) {
              console.log('Arg is X')
          }
          if (isSomeEnum(Y)(arg1)) {
              console.log('Arg is Y')
          }
      }
      
      check(X.ONE)
      check(Y.THREE)
      check(X.TWO)
      check(Y.FOUR)
      

      要完成这项工作,您需要确保枚举值不重叠,这就是为什么您需要在 Y 的定义中包含 'THREE = 3'。

      【讨论】:

        【解决方案3】:

        不可能。别忘了

        枚举是 TypeScript 为数不多的不是的功能之一 类型级 JavaScript 扩展。

        枚举允许开发人员定义一组命名常量。使用 枚举可以更容易记录意图,或创建一组 不同的案例。 TypeScript 提供基于数字和基于字符串的 枚举。

        https://www.typescriptlang.org/docs/handbook/enums.html

        在您的示例中:X.ONE = Y.THREE = 0, X.TWO = Y.FOUR = 1

        【讨论】:

          猜你喜欢
          • 2020-12-24
          • 1970-01-01
          • 1970-01-01
          • 2021-12-26
          • 2011-12-24
          • 1970-01-01
          • 2015-05-24
          • 2018-06-16
          • 1970-01-01
          相关资源
          最近更新 更多