Reputation: 1531
Updated question:
In a client-side app, I am implementing an event-handling system, similarly to how Redux works.
I define event types as subclasses of a custom Event
class. All such subclasses have their own type
static property.
I trigger an event by creating an instance of a subclass, and sending it to the main handler function.
In this main handler, I want to use type
to decide which specific handler to call.
Since an event is an instance of an Event subclass, I use event.constructor.type
.
It compiles and works fine, but the IDE complains: Property 'type' does not exist on type 'Function'
(I also marked it in the code example).
Shall I just ignore the message, or is there a better way to access that static property from an instance?
type State = {};
class Event {
public static type: string;
}
class MouseMoveEvent extends Event {
public static type = "MouseMoveEvent";
constructor(public x: number, public y: number) {
super();
}
}
class KeypressEvent extends Event {
public static type = "KeyPressEvent";
constructor(public key: string) {
super();
}
}
function handleMouseMove(event: MouseMoveEvent, state: State): State {
// return some new state
}
function handleKeyPress(event: KeyPressEvent, state: State): State {
// return some new state
}
const handlerMap: { [type: string]: (event: Event, state: State) => State; } = {
[MouseMoveEvent.type]: (event: Event, state: State) => handleMouseMove(event as MouseMoveEvent, state),
[KeyPressEvent.type]: (event: Event, state: State) => handleKeyPress(event as KeyPressEvent, state)
// etc.
};
// The main handler, it receives all triggered events, and decides which specific handler to call, based on the `type` property.
function handleEvent(event: Event, state: State): State {
// the editor complains here
return handlerMap[event.constructor.type](event, state);
}
Original question:
class BaseClass {
public static type: string;
}
class SubClass1 extends BaseClass {
public static type = "SubClass1";
}
class SubClass2 extends BaseClass {
public static type = "SubClass2";
}
const map: {[type: string]: number} = {
[SubClass1.type]: 1,
[SubClass2.type]: 2
};
function getNumber(x: BaseClass): number {
return map[x.constructor.type]; // complains here
}
const foo = new SubClass1();
console.log(getNumber(foo));
While this code compiles and works (console outputs "SubClass1"), the editor complains: Property 'type' does not exist on type 'Function'.
I tried it in Intellij Idea and the Typescript playground (www.typescriptlang.org/play). Shall I just ignore the editor message, or is there a better way to access that static property from an instance?
Upvotes: 2
Views: 1575
Reputation: 164327
You can create a type for the BaseClass
constructor:
interface BaseClassStatic {
type: string;
new (): BaseClass;
}
And then cast to it:
function getNumber(x: BaseClass): number {
return map[(x.constructor as BaseClassStatic).type];
}
Upvotes: 3