Поскольку вся информация об интерфейсах выбрасывается во время компиляции, это не будет возможно. Невозможно реализовать somedecorator для доступа к информации, которая была выбрана компилятором.
Передача имен интерфейсов декоратору в виде строк возможна, однако это не так полезно, поскольку вся информация, предоставленная интерфейсами, будет отсутствовать во время выполнения.
Хороший переполнение стека вопрос о реализации декораторов:
How to implement a typescript decorator?
Edit:
Таким образом, после исследования этого на некоторое время ответ на ваш вопрос до сих пор нет. По два причинам:
- Никакой информации об интерфейсах не может быть доступна после того, как время компиляции (с или без декораторов)
- Декораторов не получить доступ к наследуемым свойствам класса.
примеры Som для иллюстрации этого:
function myDecorator() {
// do something here..
}
interface INamed { name: string; }
interface ICounted { getCount() : number; }
interface ISomeOtherInterface { a: number; }
class SomeClass {
constructor() { }
}
class Foo implements INamed {
constructor(public name: string) { }
}
@myDecorator
class Bar extends Foo implements ICounted {
private _count: number;
getCount() : number { return this._count; }
constructor(name: string, count: number, public someProp: ISomeOtherInterface, public someClass: SomeClass) {
super(name);
this._count = count;
}
}
Это приведет к скомпилированного кода (с --emitDecoratorMetadata флагом):
function myDecorator() {
// do something here..
}
var SomeClass = (function() {
function SomeClass() {
}
return SomeClass;
})();
var Foo = (function() {
function Foo(name) {
this.name = name;
}
return Foo;
})();
var Bar = (function (_super) {
__extends(Bar, _super);
function Bar(name, count, someProp, someClass) {
_super.call(this, name);
this.someProp = someProp;
this.someClass = someClass;
this._count = count;
}
Bar.prototype.getCount = function() { return this._count; };
Bar = __decorate([
myDecorator,
__metadata('design:paramtypes', [String, Number, Object, SomeClass])
], Bar);
return Bar;
})(Foo);
Любая информация, которая будет доступна нам в декоратор (кроме класса он сам) содержится в части __decorate:
__decorate([
myDecorator,
__metadata('design:paramtypes', [String, Number, Object, SomeClass])
], Bar);
В настоящее время информация о наследовании или интерфейсах не передается вместе с декораторами. Все декораторы для класса делают, украшают конструктор. Это, вероятно, не изменится, конечно, не для интерфейсов (поскольку вся информация о них отбрасывается во время компиляции).
Как мы можем выделить массив типов __metadata, мы получаем информацию о типе для String, Number и класса SomeClass (аргументы конструктора). Но интерфейс ISomeOtherInterface отображается как Object, потому что в компилируемом javascript не сохраняется информация о интерфейсах типов. Таким образом, лучшая информация, которую мы можем получить, это Object.
Вы можете использовать что-то вроде https://github.com/rbuckton/ReflectDecorators для лучшей работы с декораторами, но вы по-прежнему сможете получить доступ к информации в __decorate и __metadata.
Итак, подведем итоги.В декораторе нет информации о наследовании или интерфейсах для класса. Интерфейсы, вероятно, никогда не будут доступны для декоратора (или где-либо еще в скомпилированном коде).
Интересно! Как я это читаю, но это только параметры (не интерфейсы и т. Д.)? По-видимому, будет невозможно достичь того, что вы хотите сделать, потому что интерфейсы отбрасываются. Я постараюсь как можно скорее взглянуть на это дальше. – Nypan
Спасибо, я не уверен, потому что эта тема не очень хорошо документирована. Я продолжил исследование и задал некоторые вопросы, связанные с этим вопросом, на https://github.com/Microsoft/TypeScript/issues/3148, если вы хотите следить за прогрессом в этом вопросе. –
Я немного посмотрел на это и протестировал его довольно много. Моему обновленным ответом для объяснений и примеров. – Nypan