Búsqueda de sitios web

javascript - Decorador de accesor y contexto de clase instanciada


No puedo entender cómo vincular el contexto de la clase instanciada en el decorador de accesor de clase. Mi clase, en resumen, es:

class A {
    protected persistProperty(a, b) {
        // ...
    }
}

class C extends A {
    @validatorTest
    public set coolStuff(email: string) {
        this.persistProperty('company.email', email);
    }
}

El decorador:

function validatorTest(
    target: any,
    propertyKey: string,
    descriptor: TypedPropertyDescriptor<string>
) {
    const oldSet = descriptor.set;

    descriptor.set = (value: string) => {
        if (value && !value.match(...)) {
            throw new Error();
        }

        oldSet(value);
    }
}

Ahora surge el problema cuando uso el accesor:

let foo = new C();

c.coolStuff = '[email ';

Recibo el siguiente error:

TypeError: Cannot read property 'persistProperty' of undefined

Entonces, como mencioné, parece que el contexto de la clase instanciada no está vinculado al decorador. ¿Qué estoy haciendo mal aquí?

Respuesta #1

Esto no es un problema de TypeScript, has perdido tu contexto de this al llamar a oldSet() sin un this.

Suposición educada: Prueba oldSet.call(this, value)

Respuesta #2

Bueno, al final descubrí el problema yo mismo... aparentemente, no se puede usar la sintaxis de flecha en las sustituciones de descriptores. Así que esto funciona como se esperaba (también gracias a la respuesta de Madara):

function validatorTest(
    target: any,
    propertyKey: string,
    descriptor: TypedPropertyDescriptor<string>
) {
    const oldSet = descriptor.set;

    descriptor.set = function(value: string) {
        if (value && !value.match(...)) {
            throw new Error();
        }

        oldSet.call(this, value);
    }
}