Pesquisa de site

javascript - Como digitar uma constante com funções definidas por string?


Digamos que eu tenha este código TypeScript:

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);

Tenho um erro com EventHandler perto do topo.

Type '{ "game:first_encounter": (data: any) => void; }' is not assignable to type '"FIRST_EVENT"'

Também tenho um erro com eventName na última linha com:

Element implicitly has an 'any' type because index expression is not of type 'number'

https://www.typescriptlang.org/play?#code/KYOwrgtgBAogajAcgFSgbwFBSgMQJIBKAysgPrxKoC8UARAOYCGEwAXAGYCWATgM4AupUAGMA9mBD9g3WgBoMAXwwYxIAbABuofgAlGIACYAbaaygBrYAE9R7KPysAHYLc3aoNTNmwBtCigA6fGIyf2QAXTMACgNGfkYzfSsASg8APnQsb2zVXlETAKNReiiAAx1gIyL7AAtpYFkoABI0WPiAgCMjMGBSRyNGK2kFUuSAbizsJSUVUTV+KDbGD3QoLp6+gaHuMwByACFu4CgAWWFDnt3G4C1JMzCgwhJyBBQlXIWb7URmNlhX6iLOKMAJfSQTDAwW66fTGaQ+MH8H4scIxYHjIA

Veja o que quero dizer? Como posso digitar isso corretamente?

Resposta #1

Vamos começar a digitar EventHandler e resolver isso.

Primeiro de tudo, é um objeto:

type EventHandlerType = {};

Ele tem chaves que são EVENTOS

// Create a mapped type mapping events to anything
type EventHandlerType = { [e in EVENT]: any }

Todo valor é uma função que recebe um parâmetro de dados e retorna void

// Create a mapped type mapping events to anything
type EventHandlerType = { [e in EVENT]: (data: any) => void };

O que deve funcionar no seu código:

const EventHandler: { [key in EVENT]: (data: any) => void } = {
    [EVENT.FIRST_EVENT]: (data: any) => {
        console.log(`Hello there, ${data.blue_player}`);
    }
}

Isso é simplificado com o tipo utilitário embutido Record, que existe para esses casos:

const EventHandler: Record<EVENT, (data: any) => void> = {
    [EVENT.FIRST_EVENT]: (data: any) => {
        console.log(`Hello there, ${data.blue_player}`);
    }
}

Veja tipos mapeados na documentação para mais exemplos e um detalhamento.