Usando el tipo de unión con genérico

Oct 27 2020

Tengo una función que acepta un parámetro que es un objeto que consta de un campo (cadena) y argumentos (objeto literal).

Me gustaría que la verificación del tipo de argumentos se validara dependiendo de cuál sea el campo. También deseo hacer una definición que pueda extenderse donde sea que necesite (de ahí el genérico).

Definición:

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

Mi función:


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

Si bien la propiedad del campo valida, los argumentos no lo hacen y dan lugar a errores (por ejemplo, con args.id):

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

¿Cómo puedo definir esto correctamente?

Respuestas

3 TitianCernicova-Dragomir Oct 27 2020 at 03:38

TypeScript no protegerá una variable basada en otra, esto simplemente no es compatible.

Si usa el argumento en sí, el análisis de flujo de control puede determinar los tipos de manera apropiada

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

Enlace de juegos