I've been experimenting with this library to improve TypeScript interaction with Vuex in my projects but I've hit a problem (or perhaps something that I misunderstood from the docs):
When I call actions via getModule(...) accessor on the first argument to the action seems to work correctly. The second argument however is always undefined inside the action.
The following example (and comments) show the problem:
Is this a bug or can actions only have a single argument (= the payload similar to vanilla vuex)?
// file SomeModule.ts
import store from '@/setup/store';
import {Action, Module, Mutation, VuexModule} from 'vuex-module-decorators';
@Module({dynamic: true, store, name: 'someModule'})
export default class SomeModule extends VuexModule {
@Action
public async doSomething(arg1: string, arg2: string) {
console.log(arg1); // has correct value of first argument
console.log(arg2); // is always undefined
}
}
```ts
// file test.ts
import {getModule} from 'vuex-module-decorators';
import SomeModule from './SomeModule';
const someModule = getModule(SomeModule.prototype);
userModule.doSomething("val1", "val2");
// results in 2 log rows, first is "val1", second is "undefined"
If you want multiple you need to pass as object or array (or use rest-spread)
The decorators aren't any magic 馃ぃ they are underlying vuex actions only 馃榿
This should be explicitly called out in the documentation, it's a very surprising and unintuitive behavior. @championswimmer I'd be happy to make a pull request adding a warning about this?
Also, would it be possible to make the types of the Action and MutationAction decorators only accept functions with zero or one parameter? Here's an example with a playground of a decorator that only accepts those functions. I'd also be happy to make a pull request implementing this.
type Func<A extends [] | [any]> = (...args: A) => any
function log<A extends [] | [any]>(
target: any,
propertyName: string,
descriptor: TypedPropertyDescriptor<Func<A>>,
) {
let method = descriptor.value
descriptor.value = function (...args: Parameters<Func<A>>): ReturnType<Func<A>> {
return (method as Func<A>)(...args)
}
}
class A {
@log
good() {
return 'string'
}
@log
good_a(a: any) {
return 'string'
}
@log
bad(a: any, b: any) {
return 'string'
}
}
https://www.typescriptlang.org/play/?experimentalDecorators=true&ssl=1&ssc=1&pln=29&pc=2#code/C4TwDgpgBAYgrgOwMYB4CCUIA9gQQEwGcoBtAXSgB9SBDBEMgPigF4oAKAOm5oCcBzQgC4oaAJStmdEACgZAM0RJgASwD2CKABs1-dJhx4ipCtRLSm7GVBtRgffhGAjpAGmu2wvNZF6gAcjQAthAihMC8Kgj87rZQ+BCESJFgwGq8IgAq4BD4AArevqAAIonJKqnpKPDI6IyM7hIA3h42Wk5QIcAAFmr4rPFlKWm8nABuNFpwEK2DScPp45PTA4rIqhoc3JwOwlB5fMFOELyE1Up1jGIiAEpOcLwI2ZDntWj1UE1Qs3G8948cLq9fo0Yg1VDvMRcHgCQhiWYAXxkSJkSC0oOIGBacQAAjp+LN+Go+uxmj9bH9gA9NABycKRaI0xFyXH4wnE-AAfRo7BoLnoZLiv3+tPpUX4TLiKNZulmACMaPhefyQK4oHKVYKhTZKdSoHSIuLJbYkQigA
I'm not an expert with Javascript annotation processing (more so in Java) but would it be possible to intercept the arguments and convert them accordingly to support the multiple Argument Syntax (probably via boxing them in an object at the call side and unboxing them in a generated method before passing them to the actual function)?
Most helpful comment
I'm not an expert with Javascript annotation processing (more so in Java) but would it be possible to intercept the arguments and convert them accordingly to support the multiple Argument Syntax (probably via boxing them in an object at the call side and unboxing them in a generated method before passing them to the actual function)?