Helo Stack Community,
I have following enum
mapping class:
export class RestEnumMpapper<T> {
constructor() {}
getEnumAsString<T>(o: T, key: string | number): string {
if (typeof key === 'string') {
return (o as T)[(o as T)[key]];
} else if (typeof key === 'number') {
return (o as T)[key];
} else {
throw new Error(`Unable to parse enum from ${typeof(key)}`);
}
}
/* ... Rest of enum converting class code ... */
}
And typical use case is following:
export class PositionEvent {
private static statusEnumMapper: RestEnumMpapper<EventState> = new RestEnumMpapper<EventState>();
/* ... */
this.status = PositionEvent.statusEnumMapper.getEnumAsString(EventState, iPos.status) as EventState;
}
It works pretty well, but I'm currently linting my code and linter complains about shadowing generic type T
in RestEnumMpapper
class here:
export class RestEnumMpapper<T> {
and here:
getEnumAsString<T>(o: T, key: string | number): string {
Which is rational and make sense to leave generic type as class type. However, when I'm dropping T
on function declaration on each call I'm getting following TypeScritp
error:
[ts] Argument of type 'typeof EventState' is not assignable to parameter of type 'EventState'.
It can be forced to work by passing value of enum (or any other plain number) but function obviously fails when trying to resolve statement like 2[3]
.
I'd be thankful for any suggestion how to fix this? Before dropping generic type in function TypeScritp was somehow able to resolve T as object with properties and just a name of enum was sufficient to work.
This happens because you are not passing in a value of the enum to the function, which would have the type EventState
but rather the object containing the enums which has type typof EventState
. So removing the type parameter from the method, but passing in typeof EventState
to the class should work fine:
let statusEnumMapper = new RestEnumMpapper<typeof EventState>();
Also might I suggest if the class is tied to a single enum as seems to be the case, you might as well pass that to the constructor, and add an index signature to T
to allow indexing without casting:
export class RestEnumMpapper<T extends { [name: string]: any }> {
constructor(public enumObject: T) { }
getEnumAsString(key: string | number): string {
if (typeof key === 'string') {
return this.enumObject[this.enumObject[key]];
} else if (typeof key === 'number') {
return this.enumObject[key];
} else {
throw new Error(`Unable to parse enum from ${typeof (key)}`);
}
}
/* ... Rest of enum converting class code ... */
}
enum EventState {
Test = "Test",
One = "One",
}
let statusEnumMapper = new RestEnumMpapper(EventState);
let statusStr = "One";
let status = statusEnumMapper.getEnumAsString(statusStr) as EventState;
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