私はデコレーターをいじくり回し、ドキュメントが出る前にこれを利用したい人のために私が見つけたものをドキュメント化することにしました。間違いを見つけた場合は、自由に編集してください。
一般的なポイント
- デコレータは、オブジェクトがインスタンス化されたときではなく、クラスが宣言されたときに呼び出されます。
- 同じClass / Property / Method / Parameterに複数のデコレータを定義できます。
- コンストラクターではデコレーターを使用できません。
有効なデコレータは次のとおりです。
- デコレータタイプのいずれかに割り当て可能(
ClassDecorator | PropertyDecorator | MethodDecorator | ParameterDecorator
)。
- デコレートされた値に割り当て可能な値(クラスデコレータおよびメソッドデコレータの場合)を返します。
参照
メソッド/正式なアクセサデコレータ
実装パラメーター:
例-引数なし
使用する:
class MyClass {
@log
myMethod(arg: string) {
return "Message -- " + arg;
}
}
実装:
function log(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) {
const originalMethod = descriptor.value; // save a reference to the original method
// NOTE: Do not use arrow syntax here. Use a function expression in
// order to use the correct value of `this` in this method (see notes below)
descriptor.value = function(...args: any[]) {
// pre
console.log("The method args are: " + JSON.stringify(args));
// run and store result
const result = originalMethod.apply(this, args);
// post
console.log("The return value is: " + result);
// return the result of the original method (or modify it before returning)
return result;
};
return descriptor;
}
入力:
new MyClass().myMethod("testing");
出力:
メソッドの引数は次のとおりです:["testing"]
戻り値は次のとおりです。メッセージ-テスト
ノート:
- 記述子の値を設定するときは、矢印構文を使用しないでください。の場合、コンテキストは
this
インスタンスのものではありません。
- 新しい記述子を返すことで現在の記述子を上書きするよりも、元の記述子を変更する方が適切です。これにより、別のデコレータが行ったことを上書きせずに記述子を編集する複数のデコレータを使用できます。これを行う
@enumerable(false)
と@log
、次のようなものを同時に使用できます(例:悪い vs 良い)
- 便利:の型引数を
TypedPropertyDescriptor
使用して、デコレータを配置できるメソッドシグネチャ(メソッドの例)またはアクセサシグネチャ(アクセサの例)を制限できます。
例-引数あり(デコレータファクトリ)
引数を使用する場合は、デコレータのパラメータを使用して関数を宣言し、引数なしで例のシグネチャを使用して関数を返す必要があります。
class MyClass {
@enumerable(false)
get prop() {
return true;
}
}
function enumerable(isEnumerable: boolean) {
return (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => {
descriptor.enumerable = isEnumerable;
return descriptor;
};
}
静的メソッドデコレータ
メソッドデコレータに似ていますが、いくつかの違いがあります。
- その
target
パラメーターは、コンストラクター関数自体であり、プロトタイプではありません。
- 記述子は、プロトタイプではなく、コンストラクター関数で定義されます。
クラスデコレータ
@isTestable
class MyClass {}
実装パラメーター:
target
:デコレータが(TFunction extends Function
)で宣言されているクラス。
使用例:メタデータAPIを使用してクラスに情報を格納します。
プロパティデコレータ
class MyClass {
@serialize
name: string;
}
実装パラメーター:
target
:クラスのプロトタイプ(Object
)。
propertyKey
:プロパティの名前(string
| symbol
)。
使用例:@serialize("serializedName")
デコレーターを作成し、シリアル化するプロパティのリストにプロパティ名を追加します。
パラメータデコレータ
class MyClass {
myMethod(@myDecorator myParameter: string) {}
}
実装パラメーター:
target
:クラスのプロトタイプ(Function
— Function
機能しなくなったようです。クラス内でデコレータを使用するには、any
またはObject
ここでを使用する必要があります。または、制限するクラスタイプを指定してください)
propertyKey
:メソッドの名前(string
| symbol
)。
parameterIndex
:関数のパラメーターのリスト内のパラメーターのインデックス(number
)。
簡単な例
詳細な例
@Injectable
デコレータにを注入したい場合は、参照してください