[解決済み】typescriptのデコレーターを実装するには?
2022-04-06 01:12:14
質問
TypeScript 1.5 は、現在 デコレータ .
誰か、デコレータを実装する適切な方法を示す簡単な例と、 有効なデコレータシグネチャの引数の意味を教えていただけませんか?
declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;
declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;
declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
declare type ParameterDecorator = (target: Function, propertyKey: string | symbol, parameterIndex: number) => void;
さらに、デコレータを実装する際に留意すべきベストプラクティスがあれば教えてください。
どのように解決するのですか?
私は結局デコレーターで遊んでいて、何かの文書が出る前にこれを利用したい人のために、私が理解したことを文書化することにしました。もし何か間違いがあれば、遠慮なく編集してください。
一般的なポイント
- デコレーターはクラスが宣言されたときに呼び出され、オブジェクトがインスタンス化されたときには呼び出されません。
- 同じクラス/プロパティ/メソッド/パラメータに複数のデコレータを定義することができます。
- デコレーターは、コンストラクターには使用できません。
有効なデコレータは以下の通りです。
- いずれかの Decorator タイプに割り当て可能 (
ClassDecorator | PropertyDecorator | MethodDecorator | ParameterDecorator
).- 装飾された値に代入可能な値 (クラス・デコレータ、メソッド・デコレータの場合) を返します。
メソッド / フォーマルアクセサデコレータ
実装パラメータです。
-
target
: クラスのプロトタイプ(Object
). -
propertyKey
: メソッドの名前 (string
|symbol
). -
descriptor
: ATypedPropertyDescriptor
- もし、記述子のキーについてよく知らないのであれば、以下の記事を読むことをお勧めします。 このドキュメント についてObject.defineProperty
(3番目のパラメータです)。
例 - 引数なし
使用します。
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
を同時に使用することができます(例. 悪い 対 良い ) -
便利な
: のtype引数は、typeを指定するためのものです。
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
).
詳細な例(s)
- メモライズデコレーター - メソッド、Get/Set Accessor デコレータの例
関連
-
[解決済み】tsconfigファイルにおけるesModuleInteropの理解
-
[解決済み] 関数デコレータを作成し、それらを連鎖させるには?
-
[解決済み] TypeScriptで文字列を数値に変換する方法とは?
-
[解決済み] Pythonの@propertyデコレーターはどのように機能するのでしょうか?
-
[解決済み] TypeScript で `window` に新しいプロパティを明示的に設定するにはどうすればよいですか?
-
[解決済み] TypeScriptでの取得と設定
-
[解決済み】TypeScriptのインターフェースと型について
-
[解決済み】TypeScriptのコンパイルでExperimental decoratorsの警告が出る。
-
[解決済み】「エラー TS2533: オブジェクトは 'null' または 'undefined' の可能性があります」を抑制する方法とは?
-
[解決済み】TypeScriptで型をnullableとして宣言する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] タイプスクリプト TS7006 です。パラメータ 'xxx' は暗黙のうちに 'any' 型を持ちます。
-
[解決済み] TypeScriptとは何ですか?なぜJavaScriptの代わりにTypeScriptを使うのですか?[クローズド]
-
[解決済み] Typescript は ?演算子をサポートしていますか?(そして、それは何と呼ばれているのでしょうか?)
-
[解決済み] ジェネリックスを使用したTypescriptのarrow関数の構文はどのようになっていますか?
-
[解決済み] オプションのパラメータを省略しながら、他のオプションのパラメータを渡すには?
-
[解決済み] AngularでNameServiceのプロバイダがない
-
[解決済み】WebStorm/PhpStormのダブルクォートでTypeScriptの自動インポートを行う。
-
[解決済み】tsconfig.jsonファイルを生成するにはどうしたらいいですか?
-
[解決済み】TypescriptのArray<Type> VS Type[]について
-
[解決済み】JSON-ObjectでTypeScriptオブジェクトを初期化する方法は?