11

デコレータを使用して、クラスによって実装されたインターフェイスの配列を取得できるかどうか知っていますか?

interface IWarrior {
  // ...
}

interface INinja {
  // ...
}

したがって、次のようなことをすると:

@somedecorator
class Ninja implements INinja, IWarrior {
 // ...
}

["INinja", "IWarrior"]実行時に、Ninja は?を含む注釈を持ちます。

ありがとう

4

2 に答える 2

2

インターフェイスに関するすべての情報はコンパイル時に破棄されるため、これは不可能です。somedecorator の実装が、コンパイラによって破棄された情報にアクセスする方法はありません。

インターフェイス名を文字列としてデコレータに渡すことは可能ですが、インターフェイスによって提供されるすべての情報が実行時に失われるため、これはあまり役に立ちません。

デコレータの実装に関する良いスタック オーバーフローの質問:

typescriptデコレータを実装するには?

編集:

したがって、これをしばらく調査した後、あなたの質問に対する答えはまだノーです。理由は 2 つあります。

  1. コンパイル後にインターフェイスに関する情報にアクセスできない (デコレータの有無にかかわらず)
  2. デコレーターは、クラスの継承されたプロパティにアクセスできません。

これを説明するいくつかの例:

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 はオブジェクトとして報告されます。これは、コンパイルされた JavaScript に typescript インターフェイスに関する情報が保持されていないためです。したがって、取得できる最良の情報はオブジェクトです。

https://github.com/rbuckton/ReflectDecoratorsのようなものを使用してデコレータをより適切に操作できますが、__decorate と __metadata の情報にしかアクセスできません。

要約すると。クラスの継承またはインターフェイスに関する情報は、デコレーターでは利用できません。インターフェイスは、デコレータ (またはコンパイルされたコードの他の場所) で使用できない可能性があります。

于 2015-05-12T11:02:50.237 に答える