TypeScriptミックスイン

提供:Dev Guides
移動先:案内検索

序章

TypeScriptでは、複数のクラスから継承または拡張することはできませんが、Mixinsはそれを回避するのに役立ちます。

ミックスインは部分クラスを作成し、それらを組み合わせて、部分クラスのすべてのメソッドとプロパティを含む単一のクラスを形成できます。

注: ドキュメントでは、このチュートリアルのアプローチを「代替パターン」として説明しています。


このチュートリアルでは、TypeScriptでミックスインを作成して使用します。

クラスの制限を理解する

ミックスインの価値を実証できるように、例を作成しましょう。

CarLorryの2つのクラスについて考えてみます。これらには、それぞれdriveメソッドとcarryメソッドが含まれています。 次に、Truckという3番目のクラスについて考えます。 Truckには、drivecarryの両方のメソッドを含める必要があります。

app.ts

export class Car {
  drive(name:string) {
    console.log(`This ${name} can drive very fast`);
  }
}

export class Lorry {
  carry(weight:number) {
    console.log(`This vehicle can carry ${weight} kg`);
  }
}

export class Truck extends Car, Lorry {}

1つのクラスしか拡張できないため、これは機能しません。

Outputerror: Classes can only extend a single class

これを解決するために、ミックスインを使用できます。

インターフェイスクラスの拡張と宣言のマージについて理解する

ミックスインを作成するために、TypeScriptの2つの機能を利用します。

インターフェイスクラス拡張

クラスとは異なり、インターフェイスはTypeScriptで複数のクラスを拡張できます。

app.ts

interface A extends ClassB, ClassC {}

インターフェイスがクラスを拡張する場合、インターフェイスには実装が含まれていないため、クラスメンバーのみが拡張され、実装は拡張されません。

宣言のマージ

2つ以上の宣言が同じ名前で宣言されている場合、TypeScriptはそれらを1つのにマージします。

app.ts

interface Alligator {
  eyes: number;
  nose: number;
}

interface Alligator {
  tail: number;
}

const gator: Alligator = {
  eyes: 2,
  nose: 1,
  tail: 1
};

gatorには、両方のAlligatorインターフェイスのプロパティが含まれています。

ヘルパー関数の使用

TypeScriptのこれら2つの機能を活用することで、Truckと同じ名前のインターフェイスを作成し、CarクラスとLorryクラスの両方を拡張できます。

app.ts

export class Truck {}
export interface Truck extends Car, Lorry {}

宣言のマージにより、TruckクラスはTruckインターフェイスとマージされます。 これは、TruckクラスにCarクラスとLorryクラスの両方の関数定義が含まれるようになることを意味します。

TruckクラスがCarおよびLorryから継承された関数を実装できるようにするには、TypeScriptdocsにあるヘルパー関数を使用します。

この関数は、実装をコピーするクラスの名前を最初の引数(この場合はTruck)として受け取り、実装をコピーするクラスの配列を2番目の引数として受け取ります。引数(この場合はCarおよびLorryです)。

app.ts

// the helper function
function applyMixins(derivedCtor: any, constructors: any[]) {
  constructors.forEach((baseCtor) => {
    Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
      Object.defineProperty(
        derivedCtor.prototype,
        name,
        Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||
          Object.create(null)
      );
    });
  });
}

そして、これがその使用方法です:

app.ts

applyMixins(Truck, [Car, Lorry]);

これで、truckオブジェクトからCarおよびLorryのメソッドにアクセスできます。

app.ts

const truck = new Truck();
truck.drive("truck");
truck.carry(10);

このコードは、次の出力を生成します。

OutputThis truck can drive very fast
This vehicle can carry 10 kg

このtruckは、drive()およびcarry()にアクセスできます。

結論

このチュートリアルでは、TypeScriptでミックスインを作成して使用しました。

ここから、インターフェイスにTypeScript宣言のマージを使用する方法を学びます。