Rematch: TypeScript gives type error in effects

Created on 8 Dec 2019  路  3Comments  路  Source: rematch/rematch

Describe the bug
I've tried some examples from docs:

import { createModel, Models, init, RematchRootState, RematchDispatch } from '@rematch/core';

const model = createModel({
    state: 0,
    reducers: {
        increment: (state: number, payload: number) => (state + payload),
    },
    effects: (dispatch: Dispatch) => ({
        incrementAsync: async () => {
            await new Promise((resolve) => setTimeout(() => resolve(), 500));

            dispatch.model.increment(1);
        },
    })
});

interface RootModel extends Models {
    model: typeof model,
}

const rootModel: RootModel = {
    model: typeof model,
}

const store = init({
    models: rootModel,
});

type Dispatch = RematchDispatch<typeof rootModel>;
type State = RematchRootState<typeof rootModel>;

And this code gives me an error in effects field of my model:

No overload matches this call.
  Overload 1 of 2, '(model: ModelConfig<number, number>): ModelConfig<number, number>', gave the following error.
    Type '(dispatch: RematchDispatch<RootModel>) => { incrementAsync: () => Promise<void>; }' is not assignable to type 'ModelEffects<any> | ((dispatch: RematchDispatch<void>) => ModelEffects<any>) | undefined'.
      Type '(dispatch: RematchDispatch<RootModel>) => { incrementAsync: () => Promise<void>; }' is not assignable to type '(dispatch: RematchDispatch<void>) => ModelEffects<any>'.
        Types of parameters 'dispatch' and 'dispatch' are incompatible.
          Type 'RematchDispatch<void>' is not assignable to type 'RematchDispatch<RootModel>'.
            Type '{ [key: string]: { [key: string]: RematchDispatcher<void, void> | RematchDispatcherAsync<void, void>; }; } & ((...args: any[]) => Action<any, any>) & ((action: Action<void, void>) => Dispatch<Action<void, void>>) & ((action: Action<...>) => Dispatch<...>) & Dispatch<...>' is not assignable to type 'RematchDispatch<RootModel>'.
              Type '{ [key: string]: { [key: string]: RematchDispatcher<void, void> | RematchDispatcherAsync<void, void>; }; } & ((...args: any[]) => Action<any, any>) & ((action: Action<void, void>) => Dispatch<Action<void, void>>) & ((action: Action<...>) => Dispatch<...>) & Dispatch<...>' is not assignable to type 'ExtractRematchDispatchersFromModels<RootModel> & ((...args: any[]) => Action<any, any>) & ((action: Action<void, void>) => Dispatch<Action<void, void>>) & ((action: Action<void, void>) => Dispatch<...>) & Dispatch<...>'.
                Property 'model' is missing in type '{ [key: string]: { [key: string]: RematchDispatcher<void, void> | RematchDispatcherAsync<void, void>; }; } & ((...args: any[]) => Action<any, any>) & ((action: Action<void, void>) => Dispatch<Action<void, void>>) & ((action: Action<...>) => Dispatch<...>) & Dispatch<...>' but required in type 'ExtractRematchDispatchersFromModels<RootModel>'.
  Overload 2 of 2, '(model: ModelConfig<any, any>): ModelConfig<any, any>', gave the following error.
    Type '(dispatch: RematchDispatch<RootModel>) => { incrementAsync: () => Promise<void>; }' is not assignable to type 'ModelEffects<any> | ((dispatch: RematchDispatch<void>) => ModelEffects<any>) | undefined'.
      Type '(dispatch: RematchDispatch<RootModel>) => { incrementAsync: () => Promise<void>; }' is not assignable to type '(dispatch: RematchDispatch<void>) => ModelEffects<any>'.

I assume this might be because of RematchDispatch type. It is incompatible with RematchDispatch.

Expected behavior
Work without any errors.

Desktop (please complete the following information):

  • OS: Window 8.1
  • Browser: Chrome 78

Additional context
TypeScript version 3.7.2

Most helpful comment

I met it too.

{
   effects: (dispatch: any) => {
      // TODO: wait to fix it
      const { MyModel } = dispatch as Dispatch;
      return {
         SomeDo() {
            MyModel.xxxx();
         } 
     };
   }
}

All 3 comments

I met it too.

{
   effects: (dispatch: any) => {
      // TODO: wait to fix it
      const { MyModel } = dispatch as Dispatch;
      return {
         SomeDo() {
            MyModel.xxxx();
         } 
     };
   }
}

I met it too.

{
   effects: (dispatch: any) => {
      // TODO: wait to fix it
      const { MyModel } = dispatch as Dispatch;
      return {
         SomeDo() {
            MyModel.xxxx();
         } 
     };
   }
}

As a temporary solution I use dispatch: RematchDispatch. It works but no method suggestions available on models.

I tried these approaches:

  1. https://rematch.github.io/rematch/#/recipes/typescript
  2. https://github.com/rematch/rematch/tree/master/examples/ts/count
  3. https://github.com/rematch/rematch/tree/master/examples/ts/strict-count

None of them work.

Thanks @onlyling for the awesome workaround!

Now I mix approach 2 with the workaround, works fine!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kdela picture kdela  路  4Comments

saraivinha85 picture saraivinha85  路  6Comments

sospedra picture sospedra  路  3Comments

linonetwo picture linonetwo  路  5Comments

alexicum picture alexicum  路  5Comments