使用装饰器获取已实现接口的列表
Using a Decorator to get list of implemented interfaces
你知道是否可以使用装饰器获得由 class 实现的接口数组:
interface IWarrior {
// ...
}
interface INinja {
// ...
}
所以如果我这样做:
@somedecorator
class Ninja implements INinja, IWarrior {
// ...
}
在 运行-time Ninja 将有一个包含 ["INinja", "IWarrior"]
?
的注释
谢谢
由于有关接口的所有信息在编译时都被丢弃,因此这是不可能的。 somedecorator 的实现无法访问已被编译器丢弃的信息。
可以将接口名称作为字符串传递给装饰器,但这并不是很有用,因为接口提供的所有信息都将在 运行 时消失。
关于实现装饰器的一个很好的堆栈溢出问题:
编辑:
所以在研究了一段时间之后,你的问题的答案仍然是否定的。有两个原因:
- 编译后无法访问有关接口的信息(有或没有装饰器)
- 装饰器无法访问 class 的继承属性。
一些例子来说明这一点:
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);
我们在装饰器中可用的任何信息(class 它本身除外)都包含在 __decorate 部分:
__decorate([
myDecorator,
__metadata('design:paramtypes', [String, Number, Object, SomeClass])
], Bar);
目前没有关于继承或接口的信息传递给装饰器。 class 的所有装饰器所做的就是装饰构造函数。这可能不会改变,对于接口肯定不会改变(因为所有关于它们的信息都会在编译时被丢弃)。
正如我们可以在 __metadata 的类型数组中看到的那样,我们获得了 String、Number 和 class SomeClass(构造函数参数)的类型信息。但是接口 ISomeOtherInterface 被报告为 Object,这是因为编译后没有保留有关 typescript 接口的信息 javascript。所以我们能得到的最好的信息就是Object。
您可以使用 https://github.com/rbuckton/ReflectDecorators 之类的东西来更好地使用装饰器,但您仍然只能访问 __decorate 和 __metadata.
中的信息
总结一下。装饰器中没有关于 class 的继承或接口的信息。装饰器(或编译代码中的其他任何地方)可能永远无法使用接口。
目前,类型仅在开发和编译时使用。类型信息不会以任何方式转换为已编译的 JavaScript 代码。但是您可以像这样将字符串列表传递给装饰器参数:
interface IWarrior {
// ...
}
interface INinja {
// ...
}
interface Function {
interfacesList: string[];
}
@interfaces(["INinja", "IWarrior"])
class Ninja implements INinja, IWarrior {
}
function interfaces(list: string[]) {
return (target: any) => {
target.interfacesList = list;
return target;
}
}
console.log(Ninja.interfacesList);
你知道是否可以使用装饰器获得由 class 实现的接口数组:
interface IWarrior {
// ...
}
interface INinja {
// ...
}
所以如果我这样做:
@somedecorator
class Ninja implements INinja, IWarrior {
// ...
}
在 运行-time Ninja 将有一个包含 ["INinja", "IWarrior"]
?
谢谢
由于有关接口的所有信息在编译时都被丢弃,因此这是不可能的。 somedecorator 的实现无法访问已被编译器丢弃的信息。
可以将接口名称作为字符串传递给装饰器,但这并不是很有用,因为接口提供的所有信息都将在 运行 时消失。
关于实现装饰器的一个很好的堆栈溢出问题:
编辑:
所以在研究了一段时间之后,你的问题的答案仍然是否定的。有两个原因:
- 编译后无法访问有关接口的信息(有或没有装饰器)
- 装饰器无法访问 class 的继承属性。
一些例子来说明这一点:
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);
我们在装饰器中可用的任何信息(class 它本身除外)都包含在 __decorate 部分:
__decorate([
myDecorator,
__metadata('design:paramtypes', [String, Number, Object, SomeClass])
], Bar);
目前没有关于继承或接口的信息传递给装饰器。 class 的所有装饰器所做的就是装饰构造函数。这可能不会改变,对于接口肯定不会改变(因为所有关于它们的信息都会在编译时被丢弃)。
正如我们可以在 __metadata 的类型数组中看到的那样,我们获得了 String、Number 和 class SomeClass(构造函数参数)的类型信息。但是接口 ISomeOtherInterface 被报告为 Object,这是因为编译后没有保留有关 typescript 接口的信息 javascript。所以我们能得到的最好的信息就是Object。
您可以使用 https://github.com/rbuckton/ReflectDecorators 之类的东西来更好地使用装饰器,但您仍然只能访问 __decorate 和 __metadata.
中的信息总结一下。装饰器中没有关于 class 的继承或接口的信息。装饰器(或编译代码中的其他任何地方)可能永远无法使用接口。
目前,类型仅在开发和编译时使用。类型信息不会以任何方式转换为已编译的 JavaScript 代码。但是您可以像这样将字符串列表传递给装饰器参数:
interface IWarrior {
// ...
}
interface INinja {
// ...
}
interface Function {
interfacesList: string[];
}
@interfaces(["INinja", "IWarrior"])
class Ninja implements INinja, IWarrior {
}
function interfaces(list: string[]) {
return (target: any) => {
target.interfacesList = list;
return target;
}
}
console.log(Ninja.interfacesList);