モジュールの拡張に入る前に、進行するにつれて役立つ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
変数には両方が含まれます bacon
と cheese
でも cheese
で宣言されました Food
クラス。 これは、インターフェースがクラスとマージされたためです。
しかし、インターフェースにメソッドが含まれている場合はどうなりますか? 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
しかし、 bake
メソッドはに表示されます food
クラスのため、intelliSenseの助けを借りて変数 Food
およびインターフェース Food
マージされ、 bake
インターフェイスには宣言のみが含まれ、実装は含まれないため、メソッドはエラーになります。 これを解決するために、の実装を追加できます bake
に Food
プロトタイプ。
Food.prototype.bake = (item) => console.log(item);
今呼び出します bake
メソッドは機能します。
food.bake("cake"); // cake
モジュール拡張を入力してください
Module augmentation は、アクセスできないサードパーティライブラリや他のファイルのクラスに機能を拡張するのに役立ちます。
私たちが持っていると言う Pet
クラスと name
プロパティと feed
方法。
export class Pet {
name: string;
feed(feedType: string) {
console.log(feedType);
}
}
次に、このクラスをインポートすることにしました。 index.ts
ファイルですが、のメソッドとプロパティのみを使用する代わりに Pet
クラスでは、さらに機能を追加したいと思います。 モジュール拡張を使用してこれを行うことができます。
まず、インポートします Pet
私たちのクラスに index.ts
ファイル。
import { Pet } from "./pet";
./pet
モジュールです。 それを拡張するために、同じ名前を使用してモジュールを宣言し、そのモジュールで、拡張しようとしているクラスと同じ名前のインターフェースを宣言します。 インターフェイスには、拡張クラスに追加するプロパティとメソッドを含めます。
declare module "./pet" {
interface Pet {
age: number;
walk(location: string);
}
}
TypeScriptは両方をマージします Pet
クラスと Pet
interface は、同じ場所にあるためです ./pet
モジュール。
しかし、それだけではありません。 インターフェイスにはメソッドの実装は含まれず、宣言のみが含まれることを説明したことを思い出してください。 そのため、の実装を追加します walk
方法 prototype
の Pet
.
Pet.prototype.walk = (location:string) => `Likes to walk in the ${location}`
これで、にあるメソッドとプロパティの両方を呼び出すことができます。 Pet
クラスと新しく宣言された Pet
インターフェース。
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ミックスインを使用する回避策があります。または、そのために作成したライブラリを使用できます。
それでおしまい。 これがお役に立てば幸いです。 😎👌