I was trying to implement a generic function that accepts an interface of functions and data, and passes the results from one another.
Inference is broken, any help will be appreciated.
Link to a CodeSandbox of the Code That Does Not Compile
function InitViewModel<S, C, M>(params: {
state: S;
computed: (s: S) => C;
methods: (s: S, c: C) => M;
}) {
const state = params.state;
const computed = params.computed(state);
const methods = params.methods(state, computed);
return {
state,
computed,
methods
};
}
export const VM = InitViewModel({
state: { message: "This Will Be Infered As expected" },
computed: (state /* infered */) => ({
computedMessage: state.message + " But This Will Not"
}),
methods: (state /* infered */, computed /* inferred wrong */) => {
return {
logName: () => console.log(state.message),
logComputedName: () => console.log(computed.computedMessage) // Does not compile
};
}
});
I believe this is not possible in the current Typescript version.
I've been experimenting with your code and it seems Type Inference work with some internal priority, which dictates that type should be inferred from parameter when possible, over inference from return value.
If you'll remove the methods parameter from your code, you'll see computed return value - C, will be inferred correctly as:
{ computedMessage: string }
When methods included,C is inferred as unknown, since it is exist as a parameter in methods, so typescript will prefer to try to get the correct type based on methods behavior rather then computed.
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