Декоратор метода TypeScript - `this` с включенным noImplicitThis - PullRequest
0 голосов
/ 18 декабря 2018

Я пытаюсь написать простой декоратор метода, который выполняет простую логику перед вызовом оригинального метода.Все примеры, которые я мог найти, сводятся к вызову originalMethod.apply(this, args) в конце - но с включенным noImplicitThis в tsconfig.json я получаю следующую ошибку:

[eval].ts(1,224): error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.

Я попытался обойти, вызвавoriginalMethod.apply(this as any, args), но ошибка сохраняется.

Вопрос: Существуют ли обходные пути для вызова исходного метода, без отключения noImplicitThis для всего проекта?


Минимальный пример - работает с noImplicitAny отключено:

function logBeforeCall1(): originalMethodDecorator {
    return function(
        target: any,
        propertyKey: string | symbol,
        descriptor: PropertyDescriptor,
    ): PropertyDescriptor {
        const originalMethod = descriptor.value;
        descriptor.value = (...args: any[]) => {
            console.log('hello!');
            return originalMethod.apply(this, args);
        };
        return descriptor;
    };
}

class Test1 {
    private num: number = 1;

    @logBeforeCall1()
    test(next: number): void {
        console.log(this.num, '->', next);
        this.num = next;
    }
}

  • Я уже знаю, что декораторы не имеют доступа к конкретному экземпляру объекта (см., например, этот вопрос ), но использование this в приведенном выше примере работает
  • Если официальные документы по декораторам используют конструкцию из моего примера (см. раздел Property Decorators ), поэтому работает , но конфликтует с noImplicitThis опцией компилятора ...

Ответы [ 2 ]

0 голосов
/ 19 декабря 2018

Спасибо @Grassator за вдохновение - эта версия работает.Я не верю, что это может быть сделано безопасно для типа в текущем состоянии TypeScript, хотя.

function logBeforeCall2(): originalMethodDecorator {
    return function(
        target: any,
        propertyKey: string | symbol,
        descriptor: PropertyDescriptor,
    ): PropertyDescriptor {
        const originalMethod = descriptor.value;
        descriptor.value = function(this: any, ...args: any[]): any {
            console.log('hello!');
            return originalMethod.apply(this, args);
        };
        return descriptor;
    };
}

...

> t2.test(5)
hello!
1 '->' 5
0 голосов
/ 18 декабря 2018

Я не думаю, что вы действительно можете получить безопасность типов, но если вы просто хотите избавиться от ошибок типов, вы можете явно сказать, что this: any (3-я строка):

function logBeforeCall1() {
  return function (
    this: any,
    target: any,
    propertyKey: string | symbol,
    descriptor: PropertyDescriptor,
  ): PropertyDescriptor {
    const originalMethod = descriptor.value;
    descriptor.value = (...args: any[]) => {
      console.log('hello!');
      return originalMethod.apply(this, args);
    };
    return descriptor;
  };
}
...