Vuex-module-decorators: Fix multiple argument problem.

Created on 5 Nov 2019  路  4Comments  路  Source: championswimmer/vuex-module-decorators

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.

  • Change the types of the 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).
  • Change the docs to give a warning about this behavior.

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!

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.

All 4 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

cyberflohr picture cyberflohr  路  4Comments

tuvokki picture tuvokki  路  7Comments

davidmoshal picture davidmoshal  路  6Comments

Leandro-Albano picture Leandro-Albano  路  3Comments

Hamidrezana picture Hamidrezana  路  4Comments