Usando tipo de união com genérico

Oct 27 2020

Eu tenho uma função que aceita um parâmetro que é um objeto que consiste em um campo (string) e argumentos (objeto literal).

Eu gostaria que a verificação de tipo de argumentos fosse validada dependendo do campo. Também desejo fazer uma definição que possa ser estendida onde eu precise (daí a genérica).

Definição:

 export interface EventDefinition<
    TField extends string,
    TArgs extends any
  > {
    field: TField
    arguments: TArgs
  }

Minha função:


export const myFn =  (
  params:
    | EventDefinition<
        'actionOne',
        {
          id: string
        }
      >
    | EventDefinition<
        'actionTwo',
        {
          emailAddress: string
        }
      >
) => {
  const { args, field } = params

  switch(field) {
    case 'actionOne':
      console.log(args.id)
      break;
      case 'actionTwo':
      console.log(args.emailAddress)
      break;
  }
}

Embora a propriedade field valide os args, não e resultam em erros (por exemplo, com args.id):

Property 'id' does not exist on type '{ id: string }'.
Property 'id' does not exist on type '{ emailAddress: string; }'.

Como posso definir isso corretamente?

Respostas

3 TitianCernicova-Dragomir Oct 27 2020 at 03:38

O texto digitado não guarda uma variável com base em outra, isso simplesmente não é suportado.

Se você usar o próprio argumento, a análise de fluxo de controle pode determinar os tipos apropriadamente

  switch(params.field) {
    case 'actionOne':
      console.log(params.arguments.id)
      break;
      case 'actionTwo':
      console.log(params.arguments.emailAddress)
      break;
  }

Link Playground