简体   繁体   中英

How to create Class-based Enums in Javascript/Typescript

I have this python code that I'm trying to convert to Javascript/Typescript

import enum

class Shape(enum.Enum):
    RECTANGLE = 0
    CIRCLE = 1
    TRIANGLE = 2
    OTHER = 3

print(isinstance(data, Shape))

In Typescript, I can use enums, but this is not what I'm looking for. I need the ability to do this:

const data = new Shape().RECTANGLE;
console.log(data instanceof Shape); // should return true

which wouldn't be possible to do using enums or objects.

EDIT: What's the syntax to build such a class-based enum in Typescript?

There isn't a specific "syntax" in TypeScript for defining a class-based enum. But here's an example of a class named Shape that recognizes four types of shapes.

Shape provides a constructor that accepts an argument shapeType . If shapeType is not a recognized type, create throws an exception.

class Shape {
  constructor(public shapeType: number) {
    if (!Shape.types.includes(shapeType)) {
      throw new Error(`Value ${shapeType} is not a valid shape type.`);
    }    
  }

  static readonly rectangle: number = 0;
  static readonly circle: number = 1;
  static readonly triangle: number = 2;
  static readonly other: number = 3;

  static get types(): number[] {
    return [
      Shape.rectangle,
      Shape.circle,
      Shape.triangle,
      Shape.other,  
    ];
  }
}

Usage:

const shape1: Shape = new Shape(Shape.triangle);
const isInstanceOf: boolean = shape1 instanceof Shape;
console.log(`Is Shape? ${isInstanceOf}; type is ${shape1.shapeType}`); // Is Shape? true; type is 2

try {
  const shape2: Shape = new Shape(42);
} catch (e) {
  console.log(e.message); // Value 42 is not a valid shape type.
}

For reasons why you might want to move from an enumeration to a class, see C# vs Java Enum (for those new to C#) .

Enums are a typescript concept, and are documented here . When you write an enum, typescript is creating a plain js object that matches the options of the enum, so the "in" operator can be used to check whether the provided value is a member of the enum.

Typescript enum.

enum Direction {
  Up,
  Down,
  Left,
  Right,
}

What that is in javascript.

var Direction = {
  '0': 'Up',
  '1': 'Down',
  '2': 'Left',
  '3': 'Right',
  Up: 0,
  Down: 1,
  Left: 2,
  Right: 3
}

Checking to see if a value is a member of the enum can be done with

const foo = "Up";

// Unsafe, but quick and easy.
console.log(foo in Direction); // returns true.
console.log("toString" in Direction); // also returns true.

// Safe.
console.log(Direction.hasOwnProperty(foo)); // returns true.
console.log(Direction.hasOwnProperty(foo)); // returns false.

This is how you can create Enums in JS/TS -

const enum OneDBServerPermission {
  RECTANGLE = 0
  CIRCLE = 1
  TRIANGLE = 2
  OTHER = 3
}

If you want to use it in other classes you can use export keyword

export const enum OneDBServerPermission {
  RECTANGLE = 0
  CIRCLE = 1
  TRIANGLE = 2
  OTHER = 3
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM