Búsqueda de sitios web

Inferir el tipo de argumento de interfaz en TypeScript


Tengamos el siguiente código:

interface Action {
  type: string;
}

interface ActionA extends Action {
  type: 'A';
  payload: number;
}

interface ActionB extends Action {
  type: 'B';
  payload: string;
}

interface Processor<T extends Action> {
  action: T;
  process: (action: T) => void;
}

// usage

const actionA: ActionA = { type: 'A', payload: 42 };

const processorA: Processor<ActionA> = {
  action: actionA,
  process(action) {
    // ...
  },
};

Ahora creo que especificar el argumento de tipo ActionA en const processorA: Processor<ActionA>=... es redundante ya que podría inferirse de action: ActionA. Desafortunadamente, Typescript reporta un error si escribo solo const processorA: Processor=....

¿Es posible mejorar las interfaces para que el argumento de tipo de Processor sea inferido?

Versión avanzada:

También me gustaría que el campo action sea del tipo T | '*'. En ese caso, el parámetro action de process(action) debería ser del tipo Action (o en el peor de los casos, simplemente any). ¿Es esto posible junto con la inferencia de parámetros de tipo mencionada anteriormente?

Respuesta #1

No hay manera en TypeScript de inferir parte del tipo de una variable. Para las variables, la inferencia es todo o nada: o dejas que el compilador lo infiera, o lo especificas en una anotación de tipo.

Puedes usar una función para inferir el tipo de la acción:

function createProcessor<T extends Action>(p: Processor<T>) {
    return p
}
const processorA = createProcessor({
  action: actionA,
  process(action) {
    // ...
  },
});

O puedes usar un IIFE como una especie de aserción de tipo elegante:

const processorA = (<T extends Action>(p: Processor<T>) => p)({
  action: actionA,
  process(action) {
    // ...
  },
});

Artículos relacionados