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?
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
...
}
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
...
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With