microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.95k stars 12.47k forks source link

Enums should have a null prototype #40740

Open matthieusieben opened 4 years ago

matthieusieben commented 4 years ago

TypeScript Version: 4.0.2

Search Terms:

Code

    const userInput = 'hasOwnProperty' as string

    enum Action {
        create,
        update
    }

    if (userInput in Action) {
      const a: Action = Action[foo as keyof typeof Action]

      console.log(typeof a) // => function
    }

Expected behavior: Transpiled enums should have a null prototype.

Actual behavior: Transpiled enums inherit from Object.prototype

Playground Link: https://www.typescriptlang.org/play?ssl=11&ssc=24&pln=9&pc=29#code/MYewdgzgLgBAZiEMC8MDkALAhhA8gdzAAUAnEABwFMSoBPNAWAChnKwBXAWxgEFgoAluBgBvZjBjASlLFEoAacTHbkAJrMrMAvs2YC4MABS4ARgCtK-AHTkyUEHSpXseQqQrU6V4FgA2vwz5BcHl4RABKcNElUEhYLAAuXn4hMBRk4LAAbQQkHBgAa0paEANHSlKM1IBdXSYJWIgQX0orXxAAc0Nyyqxw7SA

Related Issues:

MartinJohns commented 4 years ago

I believe it would be helpful if you explain your reasoning on why this should be the case, as this would be a breaking change.

matthieusieben commented 4 years ago

Well, I came upon this while trying to map user input into enum values without using a switch.

I figured the compiled version of enum was built using a regular object, and that the Enum type could actually be used as one in TS (e.g. using the in operator).

It felt kinda weired to have to check for own properties (using Object.prototype.hasOwnProperty.call(MyEnum, userInput, or MyEnum.hasOwnProperty(k)), so I used in and realized it was not safe.

Maybe there is something I am missing something but using a null prototype will definitely feel safer.

matthieusieben commented 4 years ago

A search on google on "cast string to enum typescript" yields this stack overflow link in which all answers allow hasOwnPropery to be cast into the Enum type. This is also the case for the other first google resuts.

matthieusieben commented 4 years ago

Maybe using a null prototype is not the answer but TS should provide a safe and convenient way to check if a value can be cast into an enum.