- Reflect - JavaScript | MDN
- The Reflect namespace object contains static methods for invoking interceptable JavaScript object internal methods. The methods are the same as those of proxy handlers.
Node.jsでサーバー開発をしていると、数多くのSpringの誘惑を受けます。
構造化されていて、体系的で、安易に脱獄することが難しいからです。
そのため、Node.js陣営ではNest.jsというフレームワークが誕生しました。
少なくともSpringのように構造化された形でサーバー開発をしたいという、多くの意欲があったのです。
しかし、SpringのDIはランタイムのリフレクションを利用して、言語レベルでDIを実行できるようサポートしています。
Dotnetも同様に、属性に基づいて追跡し、リフレクションでDIを実行します。
それでは、Nest.jsはどのようにDIを実行できたのでしょうか?
SpringとDotnetは基盤となる言語がコンパイラ言語であるため、言語レベルでリフレクションをサポートしていましたが、
ecma scriptはただの…インタープリタ言語の凡夫じゃないですか?
以下は、Nest.jsのチュートリアルにある例の一つです。
明らかに、このようにTypeScriptで書かれたコードはコンパイルされると型タグがすべて削除された形になり、クラスからコンストラクタに必要なargument typeが分からなくなるでしょう。
解決策は言語仕様にありました。
Reflect
幸いにも、言語レベルで各オブジェクトにメタデータを挿入するように作られた機能がありました。
単にオブジェクトにメタデータを追加し、取得する単純な機能です。
そこでTypeScriptは考えました。
それでは、クラスをコンパイルする際に型情報をメタデータに入れてみようか?
そこでTypeScriptは、クラスデコレータが付いている箇所に、該当クラスのコンストラクタに必要な引数値の情報をReflectに保存していました。
ここには、何らかのトランスフォームや黒魔術は入っておらず、純粋にTypeScriptコンパイラの機能です。
このように、該当クラスのメタデータにコンストラクタに必要な引数値の型が入っていれば、
クラスを読み込んで型が分かるため、そのまま挿入できるようになったのです。
これに関する実装はNestJSを見ても良いですが、これはあまりにも長いため、別のライブラリをお勧めします。
上記のライブラリはMicrosoftが作成したもので、コードがきれいです。
一度見てみることをお勧めします。これにて筆を置きたいと思います。
コメント0