TypeScriptでのモジュール拡張
モジュールの拡張に入る前に、進行するにつれて役立つTypeScriptのマージの原則をいくつか見てみましょう。
この投稿では、インターフェースとインターフェースのマージについて説明しました。 さらに、インターフェースをクラスとマージすることもできます。 例を見てみましょう。
class Food { cheese: string; } interface Food { bacon: string; } const food = new Food(); food.bacon = "nice bacon"; food.cheese = "sweet cheese"; console.log(food); // {bacon: "nice bacon", cheese: "sweet cheese"}
上記の例では、Food
[で宣言されていても、food
変数にはbacon
とcheese
の両方が含まれていることがわかります。 X151X]クラス。 これは、インターフェースがクラスとマージされたためです。
しかし、インターフェイスにbake
などのメソッドが含まれている場合はどうでしょうか。
class Food { cheese: string; } interface Food { bacon: string; bake(item: string); } const food = new Food(); food.bake("cake"); // Error: food.bake is not a function
ただし、クラスFood
およびインターフェイス[ X158X] Food
がマージされ、bake
メソッドを呼び出すと、インターフェイスには宣言のみが含まれ、実装は含まれないため、エラーが発生します。 これを解決するために、bake
の実装をFood
プロトタイプに追加できます。
Food.prototype.bake = (item) => console.log(item);
これで、bake
メソッドの呼び出しが機能します。
food.bake("cake"); // cake
モジュール拡張を入力してください
Module augmentation は、アクセスできないサードパーティライブラリや他のファイルのクラスに機能を拡張するのに役立ちます。
name
プロパティとfeed
メソッドを持つPet
クラスがあるとします。
pet.ts
export class Pet { name: string; feed(feedType: string) { console.log(feedType); } }
次に、このクラスをindex.ts
ファイルにインポートすることにしましたが、Pet
クラスのメソッドとプロパティだけを使用するのではなく、さらに機能を追加したいと思います。 モジュール拡張を使用してこれを行うことができます。
まず、Pet
クラスをindex.ts
ファイルにインポートします。
index.ts
import { Pet } from "./pet";
./pet
はモジュールです。 それを拡張するために、同じ名前を使用してモジュールを宣言し、そのモジュールで、拡張しようとしているクラスと同じ名前のインターフェースを宣言します。 インターフェイスには、拡張クラスに追加するプロパティとメソッドを含めます。
index.ts
declare module "./pet" { interface Pet { age: number; walk(location: string); } }
TypeScriptは、Pet
classとPet
interface の両方をマージします。これは、これらが同じ./pet
モジュールにあるためです。
しかし、それだけではありません。 インターフェイスにはメソッドの実装は含まれず、宣言のみが含まれることを説明したことを思い出してください。 そのため、Pet
のprototype
にwalk
メソッドの実装を追加します。
Pet.prototype.walk = (location:string) => `Likes to walk in the ${location}`
これで、Pet
クラスと新しく宣言されたPet
インターフェイスにあるメソッドとプロパティの両方を呼び出すことができます。
index.ts
const pet = new Pet(); pet.name = "Looty"; pet.age = 3; pet.feed("bacon"); // bacon console.log(pet.name = "Looty"); // Looty console.log(pet.age = 3); // 3 console.log(pet.walk("park")); // Likes to walk in the park
ここで、インターフェイスを宣言してからwalk
メソッドの実装をPet
プロトタイプに追加する代わりに、同じ名前のクラスを宣言しなかったのはなぜかと思うかもしれません。クラスが初期化されます。両方のクラスのメソッドがありますか?
答えは、TypeScriptではクラス間のマージが許可されていないため、同じ名前で2つ以上のクラスを作成することはできません。 クラスをマージしたい場合は、この投稿でについて説明されているTypeScriptミックスインを使用する回避策があります。または、そのために作成したライブラリを使用できます。
それでおしまい。 これがお役に立てば幸いです。 😎👌