Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enum as Parameter in TypeScript

Isn't it possible to set the type of a parameter to an Enum? Like this:

private getRandomElementOfEnum(e : enum):string{     var length:number = Object.keys(e).length;     return e[Math.floor((Math.random() * length)+1)]; } 

Following error is thrown by compilation:

Argument expression expected.(1135)

With any obviously everyhting is alright:

private getRandomElementOfEnum(e : any):string{     var length:number = Object.keys(e).length;     return e[Math.floor((Math.random() * length)+1)]; } 

This Code works fine. but isn't as elegant and typesafe.

Is there a possibility or a little workaround to define an enum as a parameter?

like image 868
Pascal Avatar asked Jun 11 '15 07:06

Pascal


People also ask

Can I use enum as a type in TypeScript?

Enums or enumerations are a new data type supported in TypeScript. Most object-oriented languages like Java and C# use enums. This is now available in TypeScript too. In simple words, enums allow us to declare a set of named constants i.e. a collection of related values that can be numeric or string values.

What is an enum in TypeScript?

In TypeScript, enums, or enumerated types, are data structures of constant length that hold a set of constant values. Each of these constant values is known as a member of the enum. Enums are useful when setting properties or values that can only be a certain number of possible values.

How does TypeScript compile enums?

TypeScript divides enum members based on their value initialization. If the value is available in the compilation phase, they are called constant members and when the value will be evaluated at runtime, they are called computed members.

Why are TypeScript enums bad?

The they are useless at runtime argument This is a false argument for typescript in general, let alone Enums. and agree, if at runtime some code tries to change the values of one of your enums, that would not throw an error and your app could start behaving unexpectedly ( that is why Object.


2 Answers

It's not possible to ensure the parameter is an enum, because enumerations in TS don't inherit from a common ancestor or interface.

TypeScript brings static analysis. Your code uses dynamic programming with Object.keys and e[dynamicKey]. For dynamic codes, the type any is convenient.

Your code is buggy: length() doesn't exists, e[Math.floor((Math.random() * length)+1)] returns a string or an integer, and the enumeration values can be manually set…

Here is a suggestion:

function getRandomElementOfEnum<E>(e: any): E {     var keys = Object.keys(e),         index = Math.floor(Math.random() * keys.length),         k = keys[index];     if (typeof e[k] === 'number')         return <any>e[k];     return <any>parseInt(k, 10); }  function display(a: Color) {     console.log(a); }  enum Color { Blue, Green }; display(getRandomElementOfEnum<Color>(Color)); 

Ideally, the parameter type any should be replaced by typeof E but the compiler (TS 1.5) can't understand this syntax.

like image 170
Paleo Avatar answered Oct 02 '22 03:10

Paleo


You can do better than any:

enum E1 {     A, B, C } enum E2 {     X, Y, Z }  function getRandomElementOfEnum(e: { [s: number]: string }): number {     /* insert working implementation here */     return undefined; }  // OK var x: E1 = getRandomElementOfEnum(E1); // Error var y: E2 = getRandomElementOfEnum(window); // Error var z: string = getRandomElementOfEnum(E2); 
like image 28
Ryan Cavanaugh Avatar answered Oct 02 '22 05:10

Ryan Cavanaugh