TS: Utility type to extract self-referencing generics

Viewed 35

Background: It's a Vuex related problem.

I want to define a utility type to apply constraint (and thus provide type hint) to Vuex's storeOptions struct. Idea be like:

type IStoreOptions<S = any> = {
  state: S;
  getters: { [k: string]: (s: S, getters: any /*  WHAT TO PUT HERE ? */) => any /* AND HERE? */ };
}

function defineStoreOptions<S>(options: IStoreOptions<S>) {
  return options;
}

const storeOptions = defineStoreOptions({
  state: {
    apple: { price: 5, count: 2 },
    banana: { price: 2, count: 5 },
  },
  getters: {
    totalCount: (state) => state.apple.count + state.banana.count,
    totalPrice: (state) => {
      return state.apple.count * state.apple.price + state.banana.count * state.banana.price
    },
    averagePrice: (state, getters) => getters.totalPrice / getters.totalCount,
  }
})

Above solution captures state's type as generic param S, thus getter function can refer to state: S and get proper type hint.

Here's my question, how can I achieve the same for second param of getter function: (state: S, getters: G) => any?

I thought about using the same technique to capture getters's type as G, but then how can I apply constraint to it?

type IStoreOptions<S = any, G = any> = {
  state: S;
  getters: G;
}

Problem is, information need for inferring getters param is self-referencing to it's wrapping object storeOptions.getters. At the same time storeOptions.getters needs to be constrained, so as to inject info of state: S.

0 Answers
Related