Добавление свойств в класс с помощью декораторов в TypeScript - PullRequest
0 голосов
/ 21 февраля 2019

На странице ссылок TypeScript's Decorator есть фрагмент кода, который иллюстрирует, как переопределить конструктор с помощью декоратора классов:

function classDecorator<T extends {new(...args:any[]):{}}>(constructor:T) {
    return class extends constructor {
        newProperty = "new property";
        hello = "override";
    }
}

@classDecorator
class Greeter {
    property = "property";
    hello: string;
    constructor(m: string) {
        this.hello = m;
    }
}

console.log(new Greeter("world"));

и в журналах:

class_1 {
  property: 'property',
  hello: 'override',
  newProperty: 'new property' }

Пока чтохорошо.НО попытка получить доступ к newProperty по точечной нотации завершается неудачно с:

Свойство 'newProperty' не существует для типа 'Greeter'.ts (2339)

error иэто не указано в подсказках в VS Code.Доступ к нему можно получить с помощью скобочных обозначений, но TS предупреждает, что

Элемент неявно имеет тип 'any', поскольку тип 'Greeter' не имеет индекса signature.ts (7017)

Я что-то пропустил?Как реализовать добавление новых свойств через декораторы безопасным для типов способом?Я хотел бы иметь нормальную поддержку компилятора, как с обычными членами класса.

1 Ответ

0 голосов
/ 21 февраля 2019

Декораторы по дизайну не могут изменить тип класса.Это все еще обсуждается и появляется до тех пор, пока предложение декоратора не будет завершено, команда не изменит поведение.Вы можете использовать mixins для этой задачи (читайте о mixins в ts )

При использовании mixins код будет выглядеть примерно так:

function classDecorator<T extends { new(...args: any[]): {} }>(constructor: T) {
    return class extends constructor {
        newProperty = "new property";
        hello = "override";
    }
}

const Greeter = classDecorator(class {
    property = "property";
    hello: string;
    constructor(m: string) {
        this.hello = m;
    }
});
type Greeter = InstanceType<typeof Greeter> // have the instance type just as if we were to declare a class

console.log(new Greeter("world").newProperty);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...