サーチ…


前書き

TypeScriptは、ECMA Script 6と同様に、クラスを使用したオブジェクト指向プログラミングをサポートしています。これは、プロトタイプベースの継承チェーンのみをサポートしていた古いJavaScriptバージョンとは対照的です。

TypeScriptのクラスサポートは、クラスが他のクラスを継承し、オブジェクトはクラスインスタンスとしてインスタンス化されますが、JavaやC#などの言語のクラスサポートと似ています。

これらの言語と同様に、TypeScriptクラスはインタフェースを実装したり、ジェネリックを利用することができます。

シンプルなクラス

class Car {
    public position: number = 0;
    private speed: number = 42;
    
    move() {
        this.position += this.speed;
    }
}    

この例では、単純なクラスのCarを宣言します。クラスには3つのメンバーがあります:プライベート・プロパティspeed 、パブリックプロパティ・position 、パブリックメソッド・move 。各メンバーはデフォルトで公開されています。だから私たちがpublicキーワードを使わなかったとしても、 move()がpublicである理由です。

var car = new Car();        // create an instance of Car
car.move();                 // call a method
console.log(car.position);  // access a public property

基本的な継承

class Car {
    public position: number = 0;
    protected speed: number = 42;
    
    move() {
        this.position += this.speed;
    }
}  

class SelfDrivingCar extends Car {

    move() {
        // start moving around :-)
        super.move();
        super.move();
    }
}

この例は、 extendsキーワードを使用してCarクラスの非常に単純なサブクラスを作成する方法を示しています。 SelfDrivingCarクラスには、オーバーライドmove()メソッドを使用し、基本クラスimplementionを使用するsuper

コンストラクタ

この例では、 constructorを使用して、基本クラスのパブリックプロパティのpositionと保護されたプロパティのspeedを宣言します。これらのプロパティはパラメータプロパティと呼ばれます 。それらは、1つの場所にコンストラクタパラメータとメンバを宣言します。

TypeScriptの中で最高のものの1つは、コンストラクタパラメータを関連するプロパティに自動的に割り当てることです。

class Car {
    public position: number;        
    protected speed: number;

    constructor(position: number, speed: number) {
        this.position = position;
        this.speed = speed;
    }
    
    move() {
        this.position += this.speed;
    }        
}

このコードはすべて単一のコンストラクタで再開できます。

class Car {
    constructor(public position: number, protected speed: number) {}
    
    move() {
        this.position += this.speed;
    }        
}

そして、どちらもTypeScript(デザインタイムとコンパイル時間)から同じ結果でJavaScriptに変換されますが、コードは大幅に少なくなります:

var Car = (function () {
    function Car(position, speed) {
        this.position = position;
        this.speed = speed;
    }
    Car.prototype.move = function () {
        this.position += this.speed;
    };
    return Car;
}());

派生クラスのコンストラクタは、基本クラスのコンストラクタをsuper()で呼び出さなければなりません。

class SelfDrivingCar extends Car {
    constructor(startAutoPilot: boolean) {
        super(0, 42);
        if (startAutoPilot) {
            this.move();
        }
    }
}

let car = new SelfDrivingCar(true);
console.log(car.position);  // access the public property position

アクセサリー

この例では、「Simpleクラス」の例を変更してspeedプロパティにアクセスできるようにします。 Typescriptアクセサを使用すると、getterまたはsetterにコードを追加できます。

class Car {
    public position: number = 0;
    private _speed: number = 42;
    private _MAX_SPEED = 100
    
    move() {
        this.position += this._speed;
    }
    
    get speed(): number {
        return this._speed;
    }

    set speed(value: number) {
        this._speed = Math.min(value, this._MAX_SPEED);
    }
}

let car = new Car();
car.speed = 120;
console.log(car.speed);  // 100

抽象クラス

abstract class Machine {
    constructor(public manufacturer: string) {
    }

    // An abstract class can define methods of it's own, or...
    summary(): string {
        return `${this.manufacturer} makes this machine.`;
    }
    
    // Require inheriting classes to implement methods
    abstract moreInfo(): string;
}

class Car extends Machine {
    constructor(manufacturer: string, public position: number, protected speed: number) {
        super(manufacturer);
    }
    
    move() {
        this.position += this.speed;
    }
    
    moreInfo() {
        return `This is a car located at ${this.position} and going ${this.speed}mph!`;
    }
}

let myCar = new Car("Konda", 10, 70);
myCar.move(); // position is now 80
console.log(myCar.summary()); // prints "Konda makes this machine."
console.log(myCar.moreInfo()); // prints "This is a car located at 80 and going 70mph!"

抽象クラスは、他のクラスを拡張できる基底クラスです。インスタンス化することはできません(つまり、 new Machine("Konda")実行することはできません)。

Typescriptの抽象クラスの2つの重要な特性は次のとおりです。

  1. 彼らは独自のメソッドを実装できます。
  2. 継承クラスで実装する必要があるメソッドを定義できます。

このため、抽象クラスは概念的にはインタフェースとクラスの組み合わせと見なすことができます

モンキーは関数を既存のクラスにパッチする

時々、新しい関数でクラスを拡張できることは有益です。たとえば、文字列をラクダの文字列に変換する必要があるとします。 stringを返すtoCamelCaseという関数がString含まれていることをTypeScriptに伝える必要がありstring

interface String {
    toCamelCase(): string;
}

これで、この関数をString実装にパッチすることができます。

String.prototype.toCamelCase = function() : string {
    return this.replace(/[^a-z ]/ig, '')
        .replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, (match: any, index: number) => {
            return +match === 0 ? "" : match[index === 0 ? 'toLowerCase' : 'toUpperCase']();
        });
}

このString拡張がロードされた場合、次のように使用できます。

"This is an example".toCamelCase();    // => "thisIsAnExample"

トランスレーション

SomeClassクラスを考えると、TypeScriptがどのようにJavaScriptに変換されるかを見てみましょう。

TypeScriptソース

class SomeClass {

    public static SomeStaticValue: string = "hello";
    public someMemberValue: number = 15;
    private somePrivateValue: boolean = false;

    constructor () {
        SomeClass.SomeStaticValue = SomeClass.getGoodbye();
        this.someMemberValue = this.getFortyTwo();
        this.somePrivateValue = this.getTrue();
    }

    public static getGoodbye(): string {
        return "goodbye!";
    }

    public getFortyTwo(): number {
        return 42;
    }

    private getTrue(): boolean {
        return true;
    }

}

JavaScriptソース

TypeScript v2.2.2を使用してv2.2.2と、出力は次のようになります。

var SomeClass = (function () {
    function SomeClass() {
        this.someMemberValue = 15;
        this.somePrivateValue = false;
        SomeClass.SomeStaticValue = SomeClass.getGoodbye();
        this.someMemberValue = this.getFortyTwo();
        this.somePrivateValue = this.getTrue();
    }
    SomeClass.getGoodbye = function () {
        return "goodbye!";
    };
    SomeClass.prototype.getFortyTwo = function () {
        return 42;
    };
    SomeClass.prototype.getTrue = function () {
        return true;
    };
    return SomeClass;
}());
SomeClass.SomeStaticValue = "hello";

観察

  • クラスのプロトタイプの修正は、 IIFEの中にラップされています
  • メンバ変数は、メインクラスfunction内で定義されfunction
  • 静的プロパティはクラスオブジェクトに直接追加され、インスタンスプロパティはプロトタイプに追加されます。


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow