devstory

Interfaces dans TypeScript

Suivez-nous sur notre fanpage pour recevoir des notifications chaque fois qu'il y a de nouveaux articles. Facebook

1- Qu'est-ce qu'une interface ?

Dans TypeScript, une interface est une construction qui déclare les normes. Les classes dérivées (derived) d'une interface doivent être conformes aux normes imposées par l'interface.
Il n'y a pas de concept d'interface dans JavaScript, par conséquent, le compilateur TypeScript ne convertit pas les interfaces en JavaScript. L'interface est utilisée comme un outil pour vérifier les types disponibles dans le programme.
TypeScript utilise le mot-clef interface pour définir une interface. Les interfaces peuvent inclure des champs (fields), des propriétés et des méthodes.

interface Greeting {
   name: string;

   sayHello(friendName:string): string; // A method

   sayBye: (friendName: string) => string; // A arrow method
}
Dans l'exemple ci-dessus, Greeting est une interface incluant 1 champ (filed) et 2 méthodes.
  • name: Un champ (field) avec le type de données string.
  • sayHello: Une méthode régulière avec un paramètre de type string, et renvoie une string.
  • sayBye: Une méthode Lambda avec un paramètre de type string, et renvoie une string. (La méthode Lambda est également appelée la méthode de flèche).

2- Interface est une type de données

L'interface est un type de données et vous pouvez créer des objets directement. Les objets créés doivent implémenter tous les champs, propriétés et méthodes déclarés dans l'interface.
Observer l'exemple suivant pour mieux comprendre :
interface_ex1.ts

interface Greeting {
    name: string;
    sayHello(friendName: string): string; // A method
    sayBye: (friendName: string) => string; // A arrow method
}
function interface_ex1_test() {
    // Create an object:
    var enPerson1: Greeting = {
        name: "John",
        sayHello: function (friendName: string): string {
            return "Hello " + friendName;
        },
        sayBye: function (friendName: string): string {
            return "Good Bye";
        }
    };
    // Create an object
    var vnPerson1: Greeting = {
        name: "Tran",
        sayHello: function (friendName: string): string {
            return "Xin Chao " + friendName;
        },
        sayBye: function (friendName: string): string {
            return "Tam biet " + friendName;
        }
    };
    // Test objects:
    console.log(enPerson1.name); // John
    console.log(enPerson1.sayHello("Tom")); // Hello Tom

    console.log(vnPerson1.name); // Tran
    console.log(vnPerson1.sayBye("Jerry")); // Tam Biet Jerry
}
interface_ex1_test(); // Call the function.
Output:

John
Hello Tom
Tran
Tam biet Jerry
Au cours de la création d'un objet directement à partir d'une interface, vous devez respecter la règle Key-Value. Cela signifie que tous les membres de cet objet sont écrits selon la règle Key-Value (Clef et valeur).

// Create an object:
var enPerson1: Greeting = {
    name: "John",
    sayHello: function (friendName: string): string {
        return "Hello " + friendName;
    },
    sayBye: function (friendName: string): string {
        return "Good Bye";
    }
};

3- Le champs facultatif

Dans TypeScript, les champs d'une interface peuvent être définis comme facultatif, ce qui signifie que la classe ou l'objet qui implémente cette interface peut les ignorer.

interface Interface_Name  {
   optional_field_name? data_type;
   // Other fields and methods (If any)
}
Dans l'exemple ci-dessous, le champ empDept est facultatif.
interface_optional_field_ex1.ts

interface IEmployee {
    empCode: number;
    empName: string;
    empDept?: string;
}
function interface_optional_field_ex1_test() {
    let tom: IEmployee = {
        empCode: 1,
        empName: "Tom"
    }
    let jerry: IEmployee = {
        empCode: 2,
        empName: "Jerry",
        empDept: "IT"
    }
    console.log(" --- tom --- ");
    console.log('tom.empName: ' + tom.empName); // Tom
    console.log('tom.empDept: ' + tom.empDept); // undefined
    console.log(" --- jerry --- ");
    console.log('jerry.empName: ' + jerry.empName); // Jerry
    console.log('jerry.empDept: ' + jerry.empDept); // IT
}
interface_optional_field_ex1_test(); // Call the function.
Output:

 --- tom ---
tom.empName: Tom
tom.empDept: undefined
 --- jerry ---
jerry.empName: Jerry
jerry.empDept: IT

4- Le champ lecture seule (Read-only)

TypeScript fournit un moyen permettant de marquer un champ en lecture seule. C'est-à-dire, lorsqu'une valeur a été attribuée à un champ, elle ne peut pas être modifiée.
Dans l'exemple ci-dessous, le champ SSN est en lecture seule. Lorsqu'une valeur lui a été attribuée, vous ne pouvez plus lui attribuer une autre valeur. Le compilateur signalera une erreur si vous commettez cette infraction.
interface_readonly_field_ex1.ts

interface Citizen {
    name: string;
    readonly SSN: number;
}
function interface_readonly_field_ex1_test() {
    let personObj: Citizen = {
        SSN: 11111,
        name: 'Tom'
    };
    personObj.name = 'Jerry'; // OK
    personObj.SSN = 22222; // Compiler Error (!!!!!)
}  
interface_readonly_field_ex1_test(); // Call the function.

5- L'interface s'étend à partir d'autres interfaces

Dans TypeScript, une interface peut s'étendre à patir d'une ou de plusieurs autres interfaces selon la syntaxe suivante :

interface C extends A, B {
   // codes..
} 
Par exemple :
interface_extends_ex1.js

interface IAnimal {
    name: string;
}
interface ICat extends IAnimal {
    age: number;
    move(): void;
}
function interface_extends_ex1_test() {
    let tom = {
        name: "Tom",
        age: 3,
        move: function () {
            console.log("Moving...");
        }
    };
    console.log(`Name: ${tom.name}`);
    console.log(`Age: ${tom.age}`);
    tom.move();
}
interface_extends_ex1_test(); // Call the function.
Output:

Name: Tom
Age: 3
Moving...

6- Implémenter les interfaces

Comme Java et C#. L'interface dans TypeScript peut être implémentée par une classe. En règle générale, une classe peut implémenter une ou plusieurs interfaces, qui doivent se conformer à la structure définie par toutes ces interfaces.

7- Function-Type Interface

TypeScript a le même concept de Functional Interface qu'en Java. On l'appelle temporairement Function-Type Interface - Une interface n'a qu'une seule méthode, et cette méthode n'a pas de nom, incluant que les paramètres et le type de retour. Function-Type Interface est utilisée comme une fonction, parfois elle dispose également des champs facultatifs.
La syntaxe pour définir Functional Interface:

interface Interface_Name  {
     (param_name_1 data_type_1, param_name_n data_type_n): return_data_type;
}
Function-Type Interface est une interface spéciale, utilisée comme une fonction et non comme un type de données.
  • Il n'est pas utile d'écrire une interface qui s'étend à partir d'une Function-Type Interface.
  • Ou il est impossible d'écrire une classe qui implémente une Function-Type Interface.
Par exemple :

interface IFormatter {
    (text:string) : number;
}
La Functional interface est utilisée comme une fonction. Observer l'exemple ci-dessous :
functional_interface_ex1.js

interface IFormatter {
    (text:string) : number;
}
function functional_interface_ex1_test()  {
   var intFormatter: IFormatter = function(text:string): number {
       return parseInt(text);
   }
   var floatFormatter: IFormatter = function(text:string): number {
       return parseFloat(text);
   }
   var text:string = "2001.55";

   var value1 = intFormatter(text); // Use as a function
   console.log(value1);  // 2001
   var value2 = floatFormatter(text); // Use as a function
   console.log(value2);  // 2001.55
} 
functional_interface_ex1_test(); // Call the function.
Output:

2001
2001.55
Function-Type Inteface peut inclure des champs facultatifs. Par exemple:
functional_interface_ex2.ts

interface IFormatter {
    (text:string) : number;
    description? : string;
}
function functional_interface_ex2_test()  {
   var intFormatter: IFormatter = function(text:string): number {
       return parseInt(text);
   }  
   intFormatter.description = "Format a string to integer";
  
   var text: string = "2001.55";
   var result = intFormatter(text); // Use as a function
   console.log(intFormatter.description);  // Format a string to integer
   console.log(result);  // 2001  
}
functional_interface_ex2_test(); // Call the function.
Output:

Format a string to integer
2001

8- Array-Type Interface

TypeScript fournit un type d'interface pour simuler un tableau qui s'appelle Array-Type Interface.
La syntaxe :

interface Interface_Name  {
    [index_name_1: index_data_type_1] : value_data_type;
    [index_name_n: index_data_type_n] : value_data_type;
    // Other properties and methods (If any) ...
}
Remarque : index_data_type_1,..., index_data_type_n doivent être différents, sinon, vous recevrez un message d'erreur :

Duplicate index signature for type 'xxx'
Par exemple :
interface_array_ex1.ts

interface IEmployeeSalary {
    [emp_name:string]:number; // emp_name --> salary
}
function interface_array_ex1_test()  {
    var salaryMap : IEmployeeSalary = {};

    salaryMap["Tom"] = 2000;  
    salaryMap["Jerry"] = 1500;  
    salaryMap["Donald"] = 3000;  

    console.log(salaryMap["Jerry"]); // 1500  
}
interface_array_ex1_test(); // Call the function.
Par exemple : une Array-Type Interface avec index_data_type est number.
interface_array_ex2.ts

interface IFootballerArray {
    [index:number]:string;
}
function interface_array_ex2_test()  {
    var footballerArray : IFootballerArray = ["Ronaldo", "Messi", "Pele"];

    console.log(footballerArray[0]); // Ronaldo
    console.log(footballerArray[1]); // Messi

    footballerArray[0.5] = "<Funny>";
    console.log(footballerArray[0.5]); // <Funny>
}
interface_array_ex2_test(); // Call the function.
Output:

Ronaldo
Messi
<Funny>
Par exemple : Une Array-Type Interface avec des champs et des méthodes :
interface_array_ex2b.ts

interface IFootballPlayerArray {
    description: string;
    someMethod(): string;
    [index: number]: string;
}
function interface_array_ex2b_test() {
    var footballerArray: IFootballPlayerArray = {
        description: "Famous Football Players",
        someMethod: function (): string {
            return "Something";
        }
    }
    footballerArray[0] = "Ronaldo";
    footballerArray[1] = "Messi";
    footballerArray[2] = "Pele";
    footballerArray[0.5] = "<Funny>";

    console.log(footballerArray.description); // Famous Football Players
    console.log(footballerArray.someMethod()); // Something
    console.log(" --- "); //  ---
    console.log(footballerArray[0]); // Ronaldo
    console.log(footballerArray[1]); // Messi
    console.log(footballerArray[0.5]); // <Funny>
}
interface_array_ex2b_test(); // Call the function.
Output:

Famous Football Players
Something
 ---
Ronaldo
Messi
<Funny>
Par exemple : Une Array-Type Interface avec des index bidimensionnels (2 dimensional indexes) :
interface_array_2d_ex1.ts

interface IStaff {
    [staff_id:number] : number; // staff_id --> salary
    [staff_number:string] : number; // staff_number --> salary
}
function interface_array_2d_ex1_test()  {
    var staffArray : IStaff = {};

    staffArray[100] = 2000;  
    staffArray[101] = 1500;  
    staffArray[102] = 3000;  

    staffArray["S-100"] = 2000;  
    staffArray["S-101"] = 1500;  
    staffArray["S-102"] = 3000;  

    console.log(staffArray[100]); // 2000  
    console.log(staffArray[102]); // 3000  
    console.log(" --- ");  
    console.log(staffArray["S-100"]); // 2000  
    console.log(staffArray["S-102"]); // 3000  
}
interface_array_2d_ex1_test(); // Call the function.
Output:

2000
3000
 ---
2000
3000