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?
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) {
// ...
},
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With