Recherche…


Introduction

TypeScript, comme ECMA Script 6, prend en charge la programmation orientée objet à l'aide de classes. Cela contraste avec les anciennes versions de JavaScript, qui ne supportaient que la chaîne d’héritage basée sur des prototypes.

Le support de classe dans TypeScript est similaire à celui de langages comme Java et C #, dans la mesure où les classes peuvent hériter d'autres classes, tandis que les objets sont instanciés en tant qu'occurrences de classe.

Aussi similaires à ces langages, les classes TypeScript peuvent implémenter des interfaces ou utiliser des génériques.

Classe simple

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

Dans cet exemple, nous déclarons une classe simple Car . La classe a trois membres: une speed propriété privée, une position propriété publique et un move méthode publique. Notez que chaque membre est public par défaut. C'est pourquoi move() est public, même si nous n'avons pas utilisé le mot-clé public .

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

Héritage de base

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();
    }
}

Cet exemple montre comment créer une sous-classe très simple de la classe Car utilisant le mot extends clé extend. La classe SelfDrivingCar remplace la méthode move() et utilise l'implémentation de la classe de base en utilisant super .

Constructeurs

Dans cet exemple, nous utilisons le constructor pour déclarer une position propriété publique et une speed propriété protégée dans la classe de base. Ces propriétés sont appelées propriétés de paramètre . Ils nous permettent de déclarer un paramètre constructeur et un membre au même endroit.

L'un des meilleurs avantages de TypeScript est l'affectation automatique des paramètres du constructeur à la propriété concernée.

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

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

Tout ce code peut être repris dans un seul constructeur:

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

Et les deux seront transférés de TypeScript (temps de conception et de compilation) en JavaScript avec le même résultat, mais en écrivant beaucoup moins de code:

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

Les constructeurs de classes dérivées doivent appeler le constructeur de classe de base avec 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

Les accesseurs

Dans cet exemple, nous modifions l'exemple "Simple class" pour autoriser l'accès à la propriété speed . Les accesseurs de typecript nous permettent d’ajouter du code supplémentaire dans les getters ou les setters.

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

Classes abstraites

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!"

Les classes abstraites sont des classes de base à partir desquelles d'autres classes peuvent s'étendre. Ils ne peuvent pas être instanciés eux-mêmes (c.-à-d. Que vous ne pouvez pas faire de new Machine("Konda") ).

Les deux caractéristiques clés d'une classe abstraite dans Typescript sont:

  1. Ils peuvent mettre en œuvre leurs propres méthodes.
  2. Ils peuvent définir des méthodes que les classes héritées doivent implémenter.

Pour cette raison, les classes abstraites peuvent être considérées comme une combinaison d'une interface et d'une classe .

Singe patch une fonction dans une classe existante

Parfois, il est utile de pouvoir étendre une classe avec de nouvelles fonctions. Par exemple, supposons qu'une chaîne soit convertie en une chaîne de casse camel. Nous devons donc dire à TypeScript, que String contient une fonction appelée toCamelCase , qui renvoie une string .

interface String {
    toCamelCase(): string;
}

Maintenant, nous pouvons corriger cette fonction dans l'implémentation 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']();
        });
}

Si cette extension de String est chargée, elle est utilisable comme ceci:

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

Transpilation

Étant donné une classe SomeClass , voyons comment le TypeScript est transposé en JavaScript.

TypeScript source

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;
    }

}

Source JavaScript

Lorsque transpiled en utilisant TypeScript v2.2.2 , la sortie est comme 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";

Observations

  • La modification du prototype de la classe est enveloppée dans un IIFE .
  • Les variables membres sont définies dans la function classe principale.
  • Les propriétés statiques sont ajoutées directement à l'objet de classe, tandis que les propriétés d'instance sont ajoutées au prototype.


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow