0

Inside my Preact application i use unistore for global state management. It all works fine except that my typescript interface is not working. This is because the actions (resolvers) are having an extra argument.

My incrementBy action is getting two arguments. The first one is the current state and the second one is the amount to increase the count by.

// Inside action (resolver)
incrementBy: (state, num): State => {
  return { ...state, count: state.count + num };
};

But when i call the function i only need to specify the amount to increase by:

// Inside component
<button onClick={() => incrementBy(8)}>
  Increase by 8
</button>

Current interface (this works for the component but (obviously) not inside the action):

interface Actions {
  incrementBy(num: number): State;
}

How can i make a single interface which works for both, so i dont have to specify multiple interfaces for every action.

Reyno
  • 6,119
  • 18
  • 27
  • It would be helpful if you could include a bit more of your code, but I'm wondering whether your code needs a little bit of a refactor to achieve what you want, are you trying to follow this example here https://www.npmjs.com/package/unistore and convert it into typescript? – Max Carroll Jun 24 '20 at 17:26
  • Can you show the entire code where you render the component? Because if I understand correctly, `incrementBy` gets injected, it's not exactly the same as the one declared in the actions. (I don't know unistore but this is what I understood from your link) – Arnaud Claudel Jun 24 '20 at 21:28
  • @ArnaudClaudel Yess that's what i realised as well, because it gets injected/connected it is a different function as the one declared in the actions. I switched to using different interfaces for this reason. – Reyno Jun 25 '20 at 07:06

1 Answers1

1

You can probably implement something like this:

export interface IIncrementParams {
  state?: State;
  num?: number;
}

interface IActions {
  incrementBy(params: IIncrementParams): State;
}

Which would allow you to do:

incrementBy({num: 8});
incrementBy({state: someState});
incrementBy({state: someState, num: 8});

Option 2 is you could provide multiple signatures:
interface IActions {
  incrementBy(num: number): State;
  incrementBy(state: State, num: number): State;
}

TypeScript function overloading

Zze
  • 18,229
  • 13
  • 85
  • 118
  • Yess this kinda worked, but instead of multiple interfaces i use a partial. Which does the same trick – Reyno Jun 25 '20 at 07:07