In this issue:
https://github.com/championswimmer/vuex-module-decorators/issues/27
it was pointed out that an Action or a MutationAction will unexpectedly and silently pass undefined for arguments past the first. This should be changed somehow, since it's very surprising and unintuitive behavior. I have two recommendations, and I'd be happy to implement them both.
Action and MutationAction decorators to only successfully compile when they're called on functions with zero or one arguments (I've given a working example of such a decorator below).Here's an example and playground of a decorator that only accepts functions with zero or one arguments.
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>> {
console.log(`from inside ${propertyName}`, ...args)
return (method as Func<A>)(...args)
}
}
class A {
@log
good() {
return 'string'
}
@log
alsoGood(a: any) {
return 'string'
}
// @log
// bad(a: any, b: any) {
// return 'string'
// }
}
const a = new A()
a.good()
a.alsoGood(1)
https://www.typescriptlang.org/play/?experimentalDecorators=true&ssl=1&ssc=1&pln=35&pc=14#code/C4TwDgpgBAYgrgOwMYB4CCUIA9gQQEwGcoBtAXSgB9SBDBEMgPigF4oAKAOm5oCcBzQgC4oaAJStmdEACgZAM0RJgASwD2CKABs1-dJhx4ipCtRLSm7GVBtRgffhGAjpAGmu2wvNZF6gAcjQAthAihMC8Kgj87rZQ+BCESJFgwGq8IgAq4BD4AArevqAAIonJKqnpKPDI6IyM7hIA3h42Wk5QIcAAFmr4rPFlKWm8nABuNFpwEK2DScPp45PTA4rIqhoc3JwOwlB5fMFOELyE1Up1jGIiAEpOcLwI2ZDntWj1UE1Qs3FIGoRqdqcHT8dgAA3k3iCUCihBUCSgABIml4fCcAkcAL5g1xQba7MQ-Wy8e6PDhdXr9GjEGqod5iLg8ASEQlxTEydkyJBaanEDAtOIAARBs34aj67GaRJsJOAD00AHJwpFogrZpyhSK4pMAQBxcX4dg0Fz0KVxOKy+VQJURKL8NVsuRxAD0zqgwt0s1dUAARjRDcaoG5fSaQGbbN6LaTFcq7Q6I272Zy-ghwkGBggIAB3USSuQ0ThiiWEgs6tT6iUARjEQA
Thanks for creating this library!
I'm not a JS expert, and maybe I'm about to say something stupid : couldn't the decorator turn all the arguments into a single object on action call and destructure it on the other side ? It would make the usage wonderfully natural!
@mullerch that would be nice! But unfortunately in js there's no way to robustly know the names of the positional arguments, so there'd be no way to build an object from them.
(The only way to do it seems to be to analyze the string representation of the function with a regex, which is a bad idea!)
For example the arguments object is just an array, and doesn't have any information about the argument names.
function f(firstArg: string, secondArg: number) {
// there's no way to get the argument names of
// `firstArg` and `secondArg` here
}
An error in the case of having the decorators on a method with more than one argument would be much appreciated. This issues has bitten me multiple times in the past because it all compiles nicely and auto-completes in my IDE but then when I go to use it it will silently fail. This is particularly frustrating when you set a default value for the 2nd argument so the code just keeps humming along but no matter what you pass in position 2+ is just ignored.
Lost quite a few hours diagnosing this issue. The problem is compounded by the fact that without {rawError: true}, highly deceptive diagnostics are given.
Most helpful comment
An error in the case of having the decorators on a method with more than one argument would be much appreciated. This issues has bitten me multiple times in the past because it all compiles nicely and auto-completes in my IDE but then when I go to use it it will silently fail. This is particularly frustrating when you set a default value for the 2nd argument so the code just keeps humming along but no matter what you pass in position 2+ is just ignored.