Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript Type Inference - Generic Object Of Functions

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
    };
  }
});
like image 302
Daniel Avatar asked Jan 21 '26 06:01

Daniel


1 Answers

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.

like image 93
yuval.bl Avatar answered Jan 22 '26 19:01

yuval.bl



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!