Skip to content

dispatcher typescript declaration fix #811

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 30, 2017
Merged

dispatcher typescript declaration fix #811

merged 1 commit into from
May 30, 2017

Conversation

kalyabin
Copy link
Contributor

With clear JavaScript Vuex.Store I can use logic like this:

const myListStore = new Vuex.Store({
    state: {
        list: []
    },
    mutations: {
        addItem: function (state, item) {
            state.list.push(item);
        }
    },
    actions: {
        getItemById: function (action, itemId) {
            return new Promise(function (resolve, reject) {
                for (var i in action.state.list) {
                    if (action.state.list[i].id == itemId) {
                        resolve(action.state.list[i]);
                        return;
                    }
                }
                reject();
            });
        }
    }
});

Using TypeScript it will be:

const myListStore = new Vuex.Store<MyStateInterface>({
    state: {
        list: []
    },
    mutations: {
        addItem: (state, item: MyItemInterface) => {
            state.list.push(item);
        }
    },
    actions: {
        getItemById: (action, itemId: number) => new Promise<MyItemInterface>((resolve, reject) => {
            for (let i in action.state.list) {
                if (action.state.list[i].id == itemId) {
                    resolve(action.state.list[i]);
                    return;
                }
            }
            reject();
        })
    }
});

But I can't use it, because returned promise in Dispatch type uses strict type:

export interface Dispatch {
  (type: string, payload?: any, options?: DispatchOptions): Promise<any[]>;
  <P extends Payload>(payloadWithType: P, options?: DispatchOptions): Promise<any[]>;
}

Is it possible to change Dispatch type?

@ktsn
Copy link
Member

ktsn commented May 30, 2017

Why this fix is related with the example code that you provided? Looks like the example includes no dispatch...

@kalyabin
Copy link
Contributor Author

kalyabin commented May 30, 2017

Full example for this fix:

export interface MyItemInterface {
    id: number;
    name: string;
}

export interface MyStateInterface {
    list: Array<MyItemInterface>
}

const myListStore = new Vuex.Store<MyStateInterface>({
    state: {
        list: []
    },
    mutations: {
        addItem: (state: MyStateInterface, item: MyItemInterface) => {
            state.list.push(item);
        }
    },
    actions: {
        getItemById: (action, itemId: number) => new Promise<MyItemInterface>((resolve, reject) => {
            for (let item of action.state.list) {
                if (item.id == itemId) {
                    resolve(item);
                }
            }
            reject();
        })
    }
});

myListStore.commit('addItem', {
    id: 1,
    name: 'first item name'
});
myListStore.commit('addItem', {
    id: 2,
    name: 'second item name'
});

myListStore.dispatch('getItemById', 1).then((item: MyItemInterface) => {
    console.log(item);
}, () => {
    console.log('item not found');
});

This code:

myListStore.dispatch('getItemById', 1).then((item: MyItemInterface) => {
    console.log(item);
}, () => {
    console.log('item not found');
});

Throws compilation exception:

error TS2345: Argument of type '(item: MyItemInterface) => void' is not assignable to parameter of type '(value: any[]) => void | PromiseLike<void>'.
  Types of parameters 'item' and 'value' are incompatible.
    Type 'any[]' is not assignable to type 'MyItemInterface'.
      Property 'id' is missing in type 'any[]'.

@ktsn
Copy link
Member

ktsn commented May 30, 2017

OK, I see.

@ktsn ktsn merged commit 11e72c6 into vuejs:dev May 30, 2017
@b-zee
Copy link

b-zee commented Aug 23, 2017

Is there a temporary solution to circumvent this problem? Or can I request that a patch version of Vuex is published to apply this fix?

@kalyabin
Copy link
Contributor Author

kalyabin commented Aug 30, 2017

I've completle fixed that problem and you can request this as a patch. @ktsn ?

@b-zee
Copy link

b-zee commented Aug 30, 2017

Version 2.4.0 has been released. It includes the fix.

https://github.com/vuejs/vuex/releases/tag/v2.4.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants