This is an old revision of the document!
Un tableau (array) est une collection homogène qui stocke des valeurs avec le même type de données
let values:string[]; values = ["1","2","3","4"] console.log(values[0]); //1 console.log(values[1]); //2
Array<T>
)let arr_names:number[] = new Array<number>(4) for(let i = 0;i<arr_names.length;i++) { arr_names[i] = i * 2 console.log(arr_names[i]) } var names:string[] = new Array<string>("Mary","Tom","Jack","Jill") for(var i = 0;i<names.length;i++) { console.log(names[i]) }
L'objet global String est un constructeur de chaînes de caractères. Les littéraux de chaînes de caractères peuvent avoir l'une des formes suivantes :
"text" 'text' "'text' in text" 'It\'s a sunny day!' //character escaping
Les objets representent la manière fondamentale dont on peut regrouper et transmettre les données. En TypeScript, nous les représentons via des types d'objets.
function imprimerForme(forme: { name: string; surface: number }) { return "Surface rectangle: " + forme.surface; }
interface Forme{ name: string; surface: number; } function imprimerForme(forme: Forme) { return "Surface rectangle: " + forme.surface; }
type Forme = { name: string; surface: number; }; function greet(forme: Forme) { return "Surface rectangle: " + forme.surface; }
Chaque propriété d'un type d'objet peut spécifier plusieurs choses: le type, si la propriété est facultative et si la propriété peut être écrite.
La plupart du temps, nous nous retrouverons face à des objets qui pourraient avoir un ensemble de propriétés. Dans ces cas, nous pouvons marquer ces propriétés comme facultatives en ajoutant un point d'interrogation (?) a la fin de leurs noms. Si on a une propriété facultative, cela veut dire qu'au moment de l'utilisation de l'objet, elle peut etre définie ou pas, comme dans l'example suivant:
interface PaintOptions { shape: Shape; //obligatoire xPos?: number; //facultatif yPos?: number; //facultatif } function paintShape(opts: PaintOptions) { // ... } const shape = getShape(); paintShape({ shape }); //valide paintShape({ shape, xPos: 100 }); //valide paintShape({ shape, yPos: 100 }); //valide paintShape({ shape, xPos: 100, yPos: 100 }); //valide
nom?: type
représente en fait une matiere plus efficace de declarer les variables comme nom: type | null | undefined
.
Par exemple:
let nom: string = null; // Incorrect, car la variable doit recevoir un string lors de l'assignation, et null n'est pas un string let nom?: string = null; // Correct, car la construction ?: signifie que nom peut etre soit string, soit null, soit undefined
Attention!. On peut aussi lire depuis les propriétés facultatives, mais TypeScript va réaliser strictNullChecks et il va nous avertir que la variable pourrait etre undefined
.
function paintShape(opts: PaintOptions) { let xPos: number = opts.xPos; // ^ = Type 'number | undefined' is not assignable to type 'number'. Type 'undefined' is not assignable to type 'number'.ts(2322) let yPos: number = opts.yPos; // ^ = Type 'number | undefined' is not assignable to type 'number'. Type 'undefined' is not assignable to type 'number'.ts(2322) }
Afin de gérer ce probleme, on peut utiliser l'opérateur ternaire.
function paintShape(opts: PaintOptions) { let xPos: number = opts.xPos === undefined ? 0 : opts.xPos; let yPos: number = opts.yPos === undefined ? 0 : opts.yPos; let xPos: number = opts.xPos ?? 0; // Si opts.xPos est null ou undefined, la variable recevra 0; sinon, l'expression évaluera le parametre de gauche }
Les propriétés peuvent également être marquées comme readonly pour TypeScript. Bien qu'il ne modifie aucun comportement lors de l'exécution, une propriété marquée comme readonly ne peut pas être écrite pendant la vérification de type.
interface Forme { readonly name: string; } function afficherInfo(obj: Forme) { // We can read from 'obj.prop'. console.log(`prop has the value '${obj.name}'.`); // But we can't re-assign it. obj.name= "hello"; // ERROR: Cannot assign to 'name' because it is a read-only property. }
L'utilisation du modificateur readonly n'implique pas nécessairement qu'une valeur est totalement immuable - ou en d'autres termes, que son contenu interne ne peut pas être modifié. Cela signifie simplement que la propriété elle-même ne peut pas être réécrite.
interface Home { readonly resident: { name: string; age: number }; } function visitForBirthday(home: Home) { // We can read and update properties from 'home.resident'. console.log(`Happy birthday ${home.resident.name}!`); home.resident.age++; } function evict(home: Home) { // But we can't write to the 'resident' property itself on a 'Home'. home.resident = { // Error: Cannot assign to 'resident' because it is a read-only property. name: "ALF student", age: 42, }; }
Soit l'interface suivante et supposons qu'on veut créer une interface qui contienne les memes propriétés, mais aussi d'autres supplémentaires. Par conséquent, on va utiliser l'extension des types, pour ne pas redéclarer une nouvelle interface presqu'identique:
interface BasicAddress { name?: string; street: string; city: string; country: string; postalCode: string; } interface AddressWithUnit extends BasicAddress { unit: string; }
Ou bien, si on veut étendre 2 interfaces, on peut utiliser:
interface Colorful { color: string; } interface Circle { radius: number; } interface ColorfulCircle extends Colorful, Circle {} const cc: ColorfulCircle = { color: "red", radius: 42, };
TypeScript fournit une autre construction appelée type intersection qui est principalement utilisée pour combiner des types d'objets existants.
Un type d'intersection est défini à l'aide de l'opérateur &
.
interface Colorful { color: string; } interface Circle { radius: number; } type ColorfulCircle = Colorful & Circle; function draw(circle: Colorful & Circle) { console.log(`Color was ${circle.color}`); console.log(`Radius was ${circle.radius}`); } // okay draw({ color: "blue", radius: 42 });
La réunion des types décrit une valeur qui peut recevoir l'un de plusieurs types. Nous utilisons la barre verticale |
pour séparer chaque type, donc number| string| boolean est le type d'une valeur qui peut être un number, une string ou un boolean.
interface Bird { fly(): void; layEggs(): void; } interface Fish { swim(): void; layEggs(): void; } declare function getSmallPet(): Fish | Bird; let pet = getSmallPet(); pet.layEggs(); // Only available in one of the two possible types pet.swim(); Property 'swim' does not exist on type 'Bird | Fish'. Property 'swim' does not exist on type 'Bird'.
Dans la programmation orientée objet, une classe est un modèle de code de programme extensible pour créer des objets, fournissant des valeurs initiales pour l'état (variables) et des implémentations de comportement (fonctions ou méthodes). En JavaScript, on peut créer des applications en utilisant cette approche basée sur les classes orientée objet. Dans TypeScript, on permet aux développeurs d'utiliser ces techniques maintenant et de les compiler en JavaScript qui fonctionne sur tous les principaux navigateurs et plates-formes, sans avoir à attendre la prochaine version de JavaScript.
class Animal { name: string; constructor(message: string) { this.name= message; } printBreed() { return "This animal is a " + this.name; } } let bear = new Greeter("bear");
Dans TypeScript, nous pouvons utiliser des modèles orientés objet courants. L'un des modèles les plus fondamentaux de la programmation basée sur les classes est de pouvoir étendre les classes existantes pour en créer de nouvelles à l'aide de l'héritage.
class Animal { name: string; constructor(theName: string) { this.name = theName; } move(distanceInMeters: number = 0) { console.log(`${this.name} moved ${distanceInMeters}m.`); } } class Snake extends Animal { constructor(name: string) { super(name); } move(distanceInMeters = 5) { console.log("Slithering..."); super.move(distanceInMeters); } } class Horse extends Animal { constructor(name: string) { super(name); } move(distanceInMeters = 45) { console.log("Galloping..."); super.move(distanceInMeters); } } let sam = new Snake("Sammy the Python"); let tom: Animal = new Horse("Tommy the Palomino"); sam.move(); tom.move(34);
Chaque classe dérivée qui contient une fonction constructor doit appeler super() qui exécutera le constructeur de la classe de base. De plus, avant d’accéder à une propriété à ce sujet dans un corps de constructeur, nous devons appeler super(). C'est une règle importante que TypeScript appliquera.
L'exemple montre également comment remplacer les méthodes de la classe de base par des méthodes spécialisées pour la sous-classe. Ici, Snake et Horse créent une méthode de déplacement qui remplace le déplacement d'Animal, lui donnant des fonctionnalités spécifiques à chaque classe. Notez que même si tom est déclaré comme un animal, puisque sa valeur est un cheval, appeler tom.move (34) appellera la méthode de substitution dans Horse.
Par défaut, tous les membres d'une classe dans TypeScript sont de type public
. Tous les membres publics sont accessibles n'importe où sans aucune restriction.
Le modificateur d'accès private
garantit que les membres de la classe ne sont visibles que pour cette classe et ne sont pas accessibles en dehors de la classe ou ils ont été créés.
Le modificateur d'accès protected
est similaire au modificateur d'accès privé, sauf que les membres protégés sont accessibles à l'aide de leurs classes dérivantes.
class Employee { public empName: string; private empEmail: string; protected empCode: number; constructor(name: string, email: string, code: number){ this.empName = name; this.empEmail = email; this.empCode = code; } } class SalesEmployee extends Employee{ private department: string; constructor(name: string, email: string, code: number, department: string) { super(name, email, code); this.department = department; } printProperties() { console.log(this.empName + " " + this.empEmail + " " + this.empCode); // ^ Property 'empEmail' is private and only accessible within class 'Employee'.ts(2341) } } let empObj = new SalesEmployee("John Smith", "john@gmail.com", 123, "Sales"); console.log(empObj); empObj.empEmail; // Property 'empEmail' is private and only accessible within class 'Employee'.ts(2341) empObj.empCode; // Property 'empCode' is protected and only accessible within class 'Employee' and its subclasses.ts(2445)
Une autre forme de créer le constructeur est à l'aide des paramètres de la classe:
constructor (public n: number, private s: number) {} /* identique à */ constructor (n: number, s: number) { this. n = n; this.s = s; }
TypeScript prend en charge les getters / setters comme moyen d'intercepter les accès à un membre d'un objet. Cela vous donne un moyen d'avoir un contrôle plus fin sur la façon dont un membre est accédé sur chaque objet.
class Employee { private _fullName: string = ""; get fullName(): string { return this._fullName; } set fullName(newName: string) { this._fullName = newName; } } let employee = new Employee(); employee.fullName = "Bob Smith"; if (employee.fullName) { console.log(employee.fullName); }
Jusqu'à présent, nous n'avons parlé que des membres d'instance de la classe, ceux qui apparaissent sur l'objet lorsqu'il est instancié. Nous pouvons également créer des membres statiques d'une classe, ceux qui sont visibles sur la classe elle-même plutôt que sur les instances. Dans cet exemple, nous utilisons static
sur origin, car il s'agit d'une valeur générale pour toutes les grilles. Chaque instance accède à cette valeur en ajoutant le nom de la classe. De même pour ajouter this. devant les accès aux instances, nous ajoutons ici Grid. devant les accès statiques.
class Grid { static origin = { x: 0, y: 0 }; calculateDistanceFromOrigin(point: { x: number; y: number }) { let xDist = point.x - Grid.origin.x; let yDist = point.y - Grid.origin.y; return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale; } constructor(public scale: number) {} } let grid1 = new Grid(1.0); // 1x scale let grid2 = new Grid(5.0); // 5x scale console.log(grid1.calculateDistanceFromOrigin({ x: 10, y: 10 })); console.log(grid2.calculateDistanceFromOrigin({ x: 10, y: 10 }));
Les classes et les interfaces sont des structures puissantes qui facilitent non seulement la programmation orientée objet, mais également la vérification de type dans TypeScript. Une classe est un plan à partir duquel nous pouvons créer des objets qui partagent la même configuration - propriétés et méthodes. Une interface est un groupe de propriétés et de méthodes associées qui décrivent un objet, mais ne fournit ni implémentation ni initialisation pour eux.
Les fonctions sont sont fondamentales toute application en JavaScript. Ils vous permettent de créer des couches d’abstraction, d’imiter des classes, de masquer des informations et de modules. Dans TypeScript, bien qu'il existe des classes, des espaces de noms et des modules, les fonctions jouent toujours le rôle clé dans la description de la façon de faire les choses.
function add(x: number, y: number): number { return x + y; }
let myAdd: (x: number, y: number) => number = function ( x: number, y: number ): number { return x + y; };
La propriété process.argv renvoie un tableau contenant les arguments de la ligne de commande transmis lors du lancement du processus Node.js. Le premier élément sera process.execPath (le chemin d'executable node). Le deuxième élément sera le chemin vers le fichier JavaScript en cours d'exécution. Les autres éléments seront des arguments de ligne de commande supplémentaires.
Lancement du processus Node.js pour le fichier process.js :
$ node process.js one 2 three
//process.js for(let argumentIndex:number = 0; argumentIndex < process.argv.length; argumentIndex++) { console.log(argumentIndex + ": " + process.argv[argumentIndex]); } /* Output: 0: C:\Program Files\nodejs\node.exe 1: C:\Users\student\Desktop\process.js 2: one 3: 2 4: three */
La fonction parseInt() analyse une chaîne de caractère fournie en argument et renvoie un entier exprimé dans une base donnée.
let string_var: string = "12"; let base: number = 10; let number_value: number = parseInt(string_var, base); console.log(number_value); //12
La fonction parseFloat() permet de transformer une chaîne de caractères en un nombre réel.
let string_var: string = "15.35"; let number_value: number = parseFloat(string_var); console.log(number_value); //15.35
node index.js NomEmp PrenomEmp ALF 3
)let newManager = new Manager("LastName", "FirstName", "Departement", 10, 30); let keyValueList: (string|number)[][]; /* Here goes your code */ console.log(keyValueList); // [["nom", "LastName"], ["prenom", "FirstName"], ["department", "Departement"], ["experience", 10], ["noSubordonnes", 30]]
interface User { name: string; age: number; occupation: string; } interface Admin { name: string; age: number; role: string; } export type Person = unknown; /* TODO: Definissez ici le type */ export const persons: User[] /* TODO: Modifiez en Person[] */ = [ { name: 'John Doe', age: 25, occupation: 'Chimney sweep' }, { name: 'Jane Doe', age: 32, role: 'Administrator' } ]; export function logPerson(user: User) { /* TODO: Modifiez pour afficher la liste des objets Person */ console.log(` - ${user.name}, ${user.age}`); } persons.forEach(logPerson);
class Pangram { private alphabet: string = 'abcdefghijklmnopqrstuvwxyz'; constructor(private phrase: string) { /* TODO */ } isPangram(): boolean { /* TODO */ return true; } }