0

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?

Bassem
  • 3,582
  • 2
  • 24
  • 47

3 Answers3

3

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#).

DavidRR
  • 18,291
  • 25
  • 109
  • 191
2

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.
Charlie Bamford
  • 1,268
  • 5
  • 18
  • Thanks Charles. Although this does help, it's not exactly what I'm looking for. I'd rather see an example using a class instead of object. – Bassem Jan 26 '21 at 18:28
  • That's not how typescript does enums. You could roll your own implementation, but you would be on your own with that. – Charlie Bamford Jan 26 '21 at 18:34
  • I don't necessarily need to use `enum`, just a basic `class` instead – Bassem Jan 26 '21 at 18:41
0

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
}
Anjs
  • 586
  • 4
  • 11