3

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?

1 Answer 1

3

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) {
    // ...
  },
});
Sign up to request clarification or add additional context in comments.

1 Comment

After introducing createProcessor tsc stucks. Offtopic: is there a way to profile tsc to see what degrades its performance?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.