デコレーターとメタデータ
実験的なデコレーターを有効にし、クラス、メソッド、プロパティのデコレーターを記述して、依存性注入のパターンにreflect-metadataを使用します。
「デコレーターとメタデータ」はCoddyKit上の無料Frontend Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはFrontend Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Frontend Academyコースには全4レッスンが含まれています。
デコレーターとは
デコレーターは、クラス、メソッド、プロパティ、パラメータを定義時に変更する関数です。Angular、NestJS、TypeORM、クラスベースのMobXで多用されています。
デコレーターの構文
クラス、メソッド、プロパティ、またはパラメータの前に@DecoratorNameを付けます。デコレーター関数はクラスが定義されたときに実行されます。
@Component({ selector: 'app-root' })
export class AppComponent {
@Input() title: string;
@HostListener('click')
onClick() {
console.log('clicked');
}
}デコレーターを有効にする
tsconfig.jsonでexperimentalフラグを有効にします。新しいECMAScript Stage 3デコレーター(TypeScript 5.0以降)ではこのフラグは不要ですが、動作の意味が異なります。
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}クラスデコレーター
コンストラクターを引数として受け取ります。クラスを置き換えたり、ラップしたり、機能を追加したりできます。
function Singleton<T extends { new (...a: any[]): {} }>(target: T) {
let instance: T;
return class extends target {
constructor(...args: any[]) {
if (!instance) instance = new target(...args) as T;
return instance;
}
};
}
@Singleton
class Logger { /* ... */ }メソッドデコレーター
(target、key、descriptor)を受け取ります。メソッドをラップできます。たとえば、呼び出しを記録できます。
function Log(target: any, key: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`[${key}]`, args);
return original.apply(this, args);
};
}
class Service {
@Log
greet(name: string) { return `Hello ${name}`; }
}プロパティデコレーター
(target、key)を受け取ります。プロパティに関する情報を登録するため、reflect-metadataと組み合わせて使われることがよくあります。
function Required(target: any, key: string) {
const existing = Reflect.getMetadata('required', target) || [];
Reflect.defineMetadata('required', [...existing, key], target);
}
class User {
@Required name: string;
@Required email: string;
}パラメーターデコレーター
(target、key、parameterIndex)を受け取ります。依存性注入で使用され、どのパラメータがどのサービスを必要とするかを記録します。
function Inject(token: string) {
return function (target: any, key: string, index: number) {
const existing = Reflect.getMetadata('inject', target, key) || {};
existing[index] = token;
Reflect.defineMetadata('inject', existing, target, key);
};
}
class UserService {
constructor(@Inject('Database') db: Database) {}
}reflect-metadata
reflect-metadataは、デコレーターがクラスのメタデータを読み書きできるようにするポリフィルです。Angular DIや多くのORMで必要になります。
npm install reflect-metadata
// main.ts (entry point):
import 'reflect-metadata';
import { Reflect } from 'reflect-metadata';
Reflect.defineMetadata('key', 'value', target);
Reflect.getMetadata('key', target); // 'value'デコレーターファクトリー
ファクトリーはデコレーターを返します。引数を渡すために使用します。
function Component(config: { selector: string }) {
return function (target: any) {
target.selector = config.selector;
};
}
@Component({ selector: 'app-root' })
class AppComponent {}バリデーションでの利用例
プロパティデコレーターとvalidate()関数を組み合わせて、小さなバリデーションライブラリを構築します。
// Decorator records that a field is required:
function Required(target: any, key: string) {
const fields = Reflect.getMetadata('required', target) || [];
Reflect.defineMetadata('required', [...fields, key], target);
}
class User {
@Required name!: string;
@Required email!: string;
}
function validate(obj: any): string[] {
const required: string[] = Reflect.getMetadata('required', obj) || [];
return required.filter(k => obj[k] == null);
}Stage 3デコレーター(TC39)
標準化されたデコレーター(TS 5.0以降、Node 22以降ではフラグ付きでサポート)は、異なるシグネチャを持ちます。experimentalフラグは不要で、reflect-metadataも必要ありません。
デコレーターを使う場面
フレームワークが提供している場合はデコレーターを使用します(Angular、NestJS、TypeORMなど)。通常のフロントエンドコードで独自のデコレーターを作るのは避けます。複雑さが増し、特定のランタイム動作に依存することになるためです。
確認問題
メタデータリフレクションを伴うレガシー(experimental)デコレーターを使うには、どのtsconfigフラグを有効にする必要がありますか。
まとめ:デコレーター
デコレーターは、クラス、メソッド、プロパティ、パラメータを定義時に変更します。experimentalDecoratorsとemitDecoratorMetadataを有効にします。クラス、メソッド、プロパティ、パラメータのデコレーターではシグネチャが異なります。reflect-metadataはメタデータを保存し、ファクトリーは引数を渡します。Angular、NestJS、TypeORMで多用されています。Stage 3デコレーター(TS 5以降)が将来の標準で、フラグは必要ありません。
よくある質問
「デコレーターとメタデータ」レッスンは無料ですか?
はい。「デコレーターとメタデータ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Frontend Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Frontend Academyコースには全4レッスンが含まれています。
「デコレーターとメタデータ」で何を学びますか?
実験的なデコレーターを有効にし、クラス、メソッド、プロパティのデコレーターを記述して、依存性注入のパターンにreflect-metadataを使用します。 ブラウザで直接実行するハンズオンコードでFrontend Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Frontend Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのFrontend Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「デコレーターとメタデータ」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このFrontend Academyレッスンでコードを書いて実行できますか?
はい。すべてのFrontend Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。