2

Can you tell if it possible to create enum like this in Typescript?

public enum FooEnum { ITEM_A(1), ITEM_B(2), ITEM_C(3); private int order; private FooEnum (int order) { this.order = order; } public int getOrder() { return order; } } 

I have enum like this:

export enum FooEnum { ITEM_A = 'ITEM_A', ITEM_B = 'ITEM_B', ITEM_C = 'ITEM_C', } 

which I am using in TypeORM entities

@Column({ type: 'enum', enum: FooEnum }) foo!: FooEnum 

I need to assign enum values to numbers to define their priority. Is possible to do that?

I had also idea to create value object with constants like you can see below but I don't know to use this class on entity, to still save Foo.ITEM_A like 'ITEM_A' string

class Foo { public static ITEM_A = new Country(1); public static ITEM_B = new Country(2); public static ITEM_C = new Country(3); constructor(order: number) { this.order = order; } readonly order: number; } 
3
  • 1
    What does Java have to do with this? Commented Dec 10, 2020 at 17:19
  • @RobertHarvey because the question pertains to porting Java code to TypeScript. Not all web devs are Java devs. Commented Dec 10, 2020 at 17:30
  • 2
    You can create a class with readonly properties and make their instances readonly. See: Recreating advanced Enum types in Typescript Commented Dec 10, 2020 at 17:42

2 Answers 2

7

This article describes a way to encapsulate static readonly instance variables using TypeScript.

"Recreating advanced Enum types in Typescript"

And here is the complete Gist (with comments):

GitHub Gist / NitzanHen / ts-enums-complete.ts

Here is an example Country "enum" class:

class Country { static readonly FRANCE = new Country('FRANCE', 1); static readonly GERMANY = new Country('GERMANY', 2); static readonly ITALY = new Country('ITALY', 3); static readonly SPAIN = new Country('SPAIN', 4); static get values(): Country[] { return [ this.FRANCE, this.GERMANY, this.ITALY, this.SPAIN ]; } static fromString(name: string): Country { const value = (this as any)[name]; if (value) return value; const cls: string = (this as any).prototype.constructor.name; throw new RangeError(`Illegal argument: ${name} is not a member of ${cls}`); } private constructor( public readonly name: string, public readonly order: number ) { } public toJSON() { return this.name; } } export default Country; 

Usage

const selectedCountry: Country = Country.FRANCE; console.log(selectedCountry.order); 
Sign up to request clarification or add additional context in comments.

3 Comments

thank you, it looks like exactly what I was looking for :) I will go try it
I tried it, value is mapped from DB, but NestJS it serializes as object in json response. I also have implemented toJSON method
@DenisStephanov The toJSON method is not a standard method... just an example getter for the name value. I would look-up how NestJS serializes a class.
0

I have modified Mr. Polywhirl's answer to have Java's values and valueOf methods in a way that can be applied to multiple enums.

function enumValues<T>(): T[] { return Object.values(this as T).filter((value) => typeof value !== "function"); }; function enumValueOf<T>(name: string): T { const value = (this as T)[name]; if (value) return value; const cls: string = (this as any).prototype.constructor.name; throw new RangeError(`Illegal argument: ${name} is not a member of ${cls}`); }; export class Country { static readonly FRANCE = new Country("FRANCE", 1); static readonly GERMANY = new Country("GERMANY", 2); static readonly ITALY = new Country("ITALY", 3); static readonly SPAIN = new Country("SPAIN", 4); private constructor( public readonly name: string, public readonly order: number ) {} static values = enumValues<Country>; static valueOf = enumValueOf<Country>; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.