7

I saw that in various stackoverflow answers on how to access an enum in html says to define a variable on the component and set it equal to the enum, like in this question. But, what would be the type?

To use their example:

enum MyEnum{
  First,
  Second
}

export class MyComponent{
  MyEnum = MyEnum;
  myEnumVar:MyEnum = MyEnum.Second
  ...
}

<div [ngSwitch]="myEnumVar">
  <div *ngSwitchCase="MyEnum.First"><app-first-component></app-first-component></div>
  <div *ngSwitchCase="MyEnum.Second"><app-second-component></app-second-component></div>
  <div *ngSwitchDefault>MyEnumVar {{myEnumVar}} is not handled.</div>
</div>

myEnumVar was typed, but MyEnum was not. What am I supposed to type it as?

0

2 Answers 2

6

Because enums are created as plain {}, their type is actually object.

For instance, the enum:

enum MyEnum{
  First,
  Second
}

is transpiled to:

var MyEnum;
(function (MyEnum) {
    MyEnum[MyEnum["First"] = 0] = "First";
    MyEnum[MyEnum["Second"] = 1] = "Second";
})(MyEnum || (MyEnum = {}));
           // ^^^^^^^^^^^ --- important part

Notice MyEnum is, in the end, an object ({}) with added properties later. More specifically, with number keys and string values (see more below).


So, if you wish to declare a type, you have some alternatives.

For starters, you can use object or any, like below (but check the other alternatives as well):

export class MyComponent{
  MyEnum:Object = MyEnum;
  myEnumVar:MyEnum = MyEnum.Second
  ...
}

Index signature type

Another option, for enums, you can also use the type {[s: number]: number | string}:

export class MyComponent{
  MyEnum:{[s: number]: number | string} = MyEnum;
  myEnumVar:MyEnum = MyEnum.Second
  ...
}

typeof

Or, as pointed by Gerrit0 (see their answer for the full info and due credits):

export class MyComponent{
  MyEnum:typeof MyEnum = MyEnum;
  myEnumVar:MyEnum = MyEnum.Second
  ...
}
4
  • thanks for the detailed answer @acdcjunior , it worked. Do you mind breaking down what { [s: number]: string } means? Why is it not reversed, like {[s: string]: number}, because enums are numbers with strings as keys?
    – evereveron
    Commented Apr 9, 2018 at 14:26
  • 1
    A couple notes - 1. Don't use Object, use object instead. Docs. 2. typeof Enum is more correct than the indexed type.
    – Gerrit0
    Commented Apr 9, 2018 at 16:10
  • @Gerrit0 Thanks for the answer and the comment. I have updated it to keep it accurate. (Guess that's what I'm supposed to do in these cases...)
    – acdcjunior
    Commented Apr 9, 2018 at 16:43
  • @evereveron Yes, structurally, that's what enums are, objects with numbers as keys (although they have strings as keys too O_o) and numbers/strings as values.
    – acdcjunior
    Commented Apr 9, 2018 at 16:44
3

While acdcjunior's answer is technically correct - yes, an enum is an object, and yes it can be described with the {[s: number]: string} type, this is not how you should type the MyEnum property.

An enum contains both string and number values, so at the very least the index signature should be { [s: number]: string | number } - MyEnum[1] === "First" while MyEnum.First === 1.

However, TypeScript provides a better way of doing this, the typeof operator. This is different from JavaScript's typeof - when you use typeof in a type declaration, it gets the type of a value and is not constrained to primitives and object.

To highlight the difference, here's an example:

enum MyEnum {
  First,
  Second
}

class MyComponent {
  static MyEnum: typeof MyEnum = MyEnum
  static MyObjectEnum: { [s: number]: string | number } = MyEnum
}

// a is `any`
// can't use MyComponent.MyObjectEnum.First
let a = MyComponent.MyObjectEnum['First']
// b is `MyEnum`
let b = MyComponent.MyEnum['First'] // or MyComponent.MyEnum.First
// c is `any`
let c = MyComponent.MyObjectEnum['Third']
// d is `any`
// using MyComponent.MyEnum.Third catches this error
let d = MyComponent.MyEnum['Third']
// neither catch this error
// e is type `string`
// f is type `string | number`
let e = MyComponent.MyEnum[3]
let f = MyComponent.MyObjectEnum[3]

If you look at the type inferred by your IDE when trying to type something, you can learn a lot about what types should be used.

intellisense

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.