Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Coding Standards] Numeric enums can lead to non-expected behaviour in the runtime #2

Open
vpanichkin opened this issue Mar 18, 2024 · 2 comments

Comments

@vpanichkin
Copy link

vpanichkin commented Mar 18, 2024

Hey,

first of all, thanks for publishing diia to the Open Source.

While reviewing the code, I saw multiple usages of the numeric enums. In fact, that's quite tricky in typescript.

export enum ResidentshipStatus {
NotActive = 0,
Active = 1,
Terminated = 2,
}

The code snippet in the runtime will be compiled to the

export var ResidentshipStatus;
(function (ResidentshipStatus) {
    ResidentshipStatus[ResidentshipStatus["NotActive"] = 0] = "NotActive";
    ResidentshipStatus[ResidentshipStatus["Active"] = 1] = "Active";
    ResidentshipStatus[ResidentshipStatus["Terminated"] = 2] = "Terminated";
})(ResidentshipStatus || (ResidentshipStatus = {}));

namely, you will get an object in the runtime with the following structure. I am sure, you didn't want to have "0","1","2" as a possible keys here.

{
    "0": "NotActive",
    "1": "Active",
    "2": "Terminated",
    "NotActive": 0,
    "Active": 1,
    "Terminated": 2
}

Solution:

  1. Using enum with the String values:
enum ResidentshipStatus { 
     NotActive = 'notActive', 
     Active = 'active', 
     Terminated = "terminated', 
 } 

will be converted in the runtime to

{
    "NotActive": "notActive",
    "Active": "active",
    "Terminated": "terminated"
}
  1. Use object with as const modifier
const ResidentshipStatus = {
    NotActive: 'notActive',
    Active: 'active',
    Terminated: 'terminated',
} as const;

type ResidentshipStatus = typeof ResidentshipStatus[keyof typeof ResidentshipStatus];

In the Javascript runtime, the object will be

"use strict";
const ResidentshipStatus = {
    NotActive: 'notActive',
    Active: 'active',
    Terminated: 'terminated',
};

while the type will stay in the Typescript

More details about this topic can be found using the following links:

@degloman
Copy link

@vpanichkin I belive it is done intentionally, because this field is stored and taken from the database.
Integers reduce database space and improves performance.

@Fire-cell
Copy link

@vpanichkin I belive it is done intentionally, because this field is stored and taken from the database. Integers reduce database space and improves performance.

The issue doesn't lie with numbers, root of all is in enum type because it has unpredictable behavior as @vpanichkin described quite well. If numerical values are necessary they can write code like this below:

const ResidentshipStatus = {
NOT_ACTIVE: 0,
ACTIVE: 1,
TERMINATED: 2
} as const

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants