Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Infer interface type argument in TypeScript

Let's have a following code:

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) {
    // ...
  },
};

Now I think that specifying type argument ActionA in const processorA: Processor<ActionA> = ... is redundant as it could be inferred from action: ActionA. Unfortunately Typescript reports error if I write just const processorA: Processor = ....

Is it possible to improve interfaces so that type argument of Processor would be inferred?

Advanced version:

I would also like action field to be of type T | '*'. In that case action parameter of process(action) should be of type Action (or in worst case just any). Is this possible together with above mentioned type parameter inferring?

like image 496
Martin Ždila Avatar asked Mar 08 '26 00:03

Martin Ždila


1 Answers

There is no way in typescript to infer part of a variable type. For variables inference is all or nothing, you either let the compiler infer it, or you specify it in a type annotation.

You can use a function to infer the type of the action:

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

Or you can use an IIFE as a kind of fancy type assertion:

const processorA = (<T extends Action>(p: Processor<T>) => p)({
  action: actionA,
  process(action) {
    // ...
  },
});
like image 106
Titian Cernicova-Dragomir Avatar answered Mar 10 '26 03:03

Titian Cernicova-Dragomir