Reputation: 447
Let's say I have this TypeScript code:
enum EVENT {
FIRST_EVENT = "game:first_encounter",
}
const EventHandler: keyof typeof EVENT = {
[EVENT.FIRST_EVENT]: (data: any) => {
console.log(`Hello there, ${data.blue_player}`);
}
}
const data = { blue_player: 'Blue McBlue', event: EVENT.FIRST_EVENT}
const eventName: EVENT = data.event;
EventHandler[eventName](data);
I have an error with EventHandler
near the top.
Type '{ "game:first_encounter": (data: any) => void; }' is not assignable to type '"FIRST_EVENT"'
I also have an error of with eventName
on the last line with:
Element implicitly has an 'any' type because index expression is not of type 'number'
See what I mean? How can I correctly type this?
Upvotes: 2
Views: 52
Reputation: 276446
Let's start typing EventHandler
and figure this out.
First of all it's an object:
type EventHandlerType = {};
It has keys that are EVENTs
// Create a mapped type mapping events to anything
type EventHandlerType = { [e in EVENT]: any }
Every value is a function that takes a data parameter and returns void
// Create a mapped type mapping events to anything
type EventHandlerType = { [e in EVENT]: (data: any) => void };
Which should work in your code:
const EventHandler: { [key in EVENT]: (data: any) => void } = {
[EVENT.FIRST_EVENT]: (data: any) => {
console.log(`Hello there, ${data.blue_player}`);
}
}
This is made simpler with the built in utility type Record
which exists for these cases:
const EventHandler: Record<EVENT, (data: any) => void> = {
[EVENT.FIRST_EVENT]: (data: any) => {
console.log(`Hello there, ${data.blue_player}`);
}
}
See mapped types in the docs for more examples and a drill down.
Upvotes: 2