Développer en TypeScript
Introduction
Qu'est ce que TypeScript ?
TypeScript est un langage pour développer des applications conséquentes en JavaScript. Il permet d'ajouter des types optionnels, qui associés à des outils permet le développement d'applications JavaScript importantes, pour n'importe quelle navigateur, hote ou environnement d'exploitation. Le TypeScript est compilé en JavaScript.
>> Installation : npm i typescript --save-dev
Pourquoi utiliser TypeScript ? Il y a 2 raisons principales :
- Le système de types introduit par TypeScript permet d'éviter les problèmes avec les types dynamiques qui sont fréquémment rencontrés avec JS
- TypeScript implemente les dernières fonctionnalités ES Next (https://www.javascripttutorial.net/es-next/)
Qu'est que ts-node ?
ts-node est un moteur d'execution TypeScript et également un REPL for Node.js.
Un REPL (“REP-UL”) est une manière interactive d'interagir avec Node. L'acronyme REPL signifie :
- "Read" : lecture de la commande utilisateur.
- "Evaluate" : évaluation (execution) du code.
- "Print" : affichage des résultats
- "Loop" : reprendre à l'étape 1, pour une nouvelle instruction
ts-node va procéder à une transformation JIT ("Just in Time") du TypeScript en JavaScript et permettre ainsi l'éxecution sans précompilation. Ceci est fait en "s'accrochant" (via hook) au module de chargement des API de Node.
Pour créer un nouveau projet TypeScript
- npm init -y ; initialiser un projet
- npm i typescript --save-dev : install le package TypeScript dans le projet
- npx tsc --init : initialise le TypeScript
Types in TypeScript
TypeScript hérite des types natifs de JavaScript. Les types TypeScript sont de 2 catégories :
Les types primitifs :
Name Description
string chaine de caractères
number valeurs numériques
boolean valeur vrai et faux
null la valeur nulle
undefined la valeur "non définie". C'est la valeur par défaut pour toute variable non initialisée.
symbol represente une valeur unique et constante
Les types objet
Les types objets sont les fonctions, les tableaux, les classes...
A quoi servent les types en TypeScript ?
Dans un premier temps, ils permettent au compilateur d'analyser le code et d'identifier d'éventuelles erreurs. Dans un second temps, le typage permet de mieux comprendre les valeurs associées aux variables.
Les Annotations TypeScript
TypeScript utilise des annotations pour spécifier explicitement les types des identifiants, tels que les variables, les fonctions, ou encore les objets...
TypeScript utilise la syntaxe ": type" après un identifiant, ou type doit etre un type valide. Une fois annoté, et donc typé, l'identifiant utilisé ne pourra pas être retypé, et son utilisation en tant que type différent entrainera une erreur du compilateur.
Exemples de syntaxe d'annotation :
let variableName: type;
let variableName: type = value;
const constantName: type = value;
Exemple d'annotations :
let nftName: string = 'Magic Owl';
let total: number = 25;
let active: boolean = true;
L'annotation d'un tableau utilise la syntaxe " : type[]"
let arrayName: type[];
Pour un tableau de string :
let names: string[] = ['John', 'Jane', 'Peter', 'David', 'Mary'];
Objets
La définition d'un type objet utilise la syntaxe pour annotation de type objet :
let nft: {
name: string;
id: number
};
Fonctions : Arguments et type retour
Exemple de déclaration en utilisant l'annotation des pramètres et l'annotation du type retour :
let greeting : (name: string) => string;
Cette déclaration désigne une fonction qui accepte un paramètre de type string et retourne un type string en valeur de retour :
greeting = function (name: string) {
return `Hi ${name}`;
};
Adressage des problématiques de types dynamiques
Les paramètres des fonctions peuvent être typées, ce qui permet d'éviter les erreurs dans l'ordre des paramètres, puisque les erreurs de type seront detectées par l'IDE.
const showProduct = (name: string, price:number) => {
console.log(`The product ${name} costs ${price}$.`);
};
Une pratique consiste à déclarer une interface :
interface Nft{
id: number,
name: string,
price: number
};
Ensuite ce type peut petre utilisé comme type de retour par exemple :
function getNft(id) : Nft{
return {
id: id,
name: `Awesome Monkey ${id}`,
price: 99.5
}
}
En TypeScript, on peut définir un type comme une manière pratique de faire référence aux propriétés et métodes disponibles pour une valeur.
Inférence de Types
- L'inférence de type se produit lorsque l'on initialise une varibable, lorsque l'on assigne une valeur par défault à un paramètre, et lors de la détermination d'un type retour
- TypeScript utilise l'algorithme du meilleur type commune pour selectionner le type candidat compatible avec toutes les variables.
- TypeScript utilise également la frappe contextuelle pour inférer des types de variables en fonction de leur localisation.
Type Nombre
Tous les nombres en TypeScript sont soit des valeurs à virguel flottante (number) ou de grands entiers (bigint).
En TypeScript comme en JavaScript les types numériques supportés sont :
Décimale
let counter: number = 0;
let x: number = 100,
y: number = 200;
Binaire
La notation binaire utilise un zéro en tête suivi de la lettre b/B :
let bin = 0b100;
let anotherBin: number = 0B010;
Evidemment les chiffres suivant le b/B doivent être des 0 ou des 1.
Octale
La notation octale utiliuse la lettre o :
let octal: number = 0o10;
Evidemment les chiffres suivant le o doivent être compris entre 0 et 7.
Héxadécimale
La notation binaire utilise un zéro en tête suivi de la lettre x/X :
let hexadecimal: number = 0XA;
Evidemment les chiffres suivant le o doivent appartenir à l'ensemble 0123456789ABCDEF.
Attention, JavaScript propose le type Number (N majuscule) en référence au type non primif d'objet boxé/ L'utilisation de ce type est éviter.
Grand Entier
Les nombres dont la valeur est inférieure à 2^53-1. On appose un "n" à la suite du nombre :
let big: bigint = 9007199254740991n;
Type Chaine de Caractères
Commen JavaScript les guillemets simples ( ' ) ou doubles ( " ) sont utilisés pour délimiter les chaines de caractères. TypeScript supporte également le backtick ( ` ) pour travailler avec des chaines modèles, disposées sur plusieurs lignes ou faisant appel l'interpolation de chaines.
let description = `This TypeScript string can
span multiple
lines
`;
String interpolations :
let firstName: string = `John`;
let title: string = `Web Developer`;
let profile: string = `I'm ${firstName}.
I'm a ${title}`;
console.log(profile);
Type Booléen
let pending: boolean;
pending = true;
// after a while
// ..
pending = false;
Attention comme pour number et Number, on trouve boolean et Boolean (fait référence au type non primitif boxé).
Type Objet
Déclaration d'une variable de type object :
let employee: object;
employee = {
firstName: 'John',
lastName: 'Doe',
age: 25,
jobTitle: 'Web Developer'
};
console.log(employee);
Output:
{
firstName: 'John',
lastName: 'Doe',
age: 25,
jobTitle: 'Web Developer'
}
Si l'on souhaite spécifier le type des propriétés de l'objet on peut
Séparer la déclaration et l'initialisation :
let employee: {
firstName: string;
lastName: string;
age: number;
jobTitle: string;
};
Code language: CSS (css)
And then you assign the employee object to a literal object with the described properties:
employee = {
firstName: 'John',
lastName: 'Doe',
age: 25,
jobTitle: 'Web Developer'
};
Faire les 2 en même temps :
let employee: {
firstName: string;
lastName: string;
age: number;
jobTitle: string;
} = {
firstName: 'John',
lastName: 'Doe',
age: 25,
jobTitle: 'Web Developer'
};
object vs Object
En TypeScript , il existe également un type Object (O majuscule).
object : type qui représente toutes les valeurs non primitives
Object: décrit les fonctionnalités de tous les objects (ex : toString(), valueOf()...)
Type Tableau
Le type tableu fait référence à une liste ordonnée de données. Pour déclarer un tableau typé, on utilise la syntaxe suivante :
let arrayName: type[];
Pour un tableau de chaines de caractères par exemple :
let skills: string[];
On peut ensuite lui ajouter des valeurs directement par assignation :
skills[0] = "Problem Solving";
skills[1] = "Programming";
ou en utilisant la méthode push()
skills.push('Software Design');
Déclaration d'un tableau de string à l'aide d l'inférence de type :
let skills = ['Problem Sovling','Software Design','Programming'];
Ce qui est équivalent à :
let skills: string[];
skills = ['Problem Sovling','Software Design','Programming'];
Propriétés et Méthodes du type Tableau
Lenght, forEach, map, reduce, filter
ex :
let series = [1, 2, 3];
let doubleIt = series.map(e => e* 2);
console.log(doubleIt);
Output:
[ 2, 4, 6 ]
Déclarer un tableau multi-types :
let scores = ['Programming', 5, 'Software Design', 4];
TypeScript infère le tableau scores comme un tableau de type string | number :
let scores : (string | number)[];
scores = ['Programming', 5, 'Software Design', 4];
Les Tuples
Un Tuple se comporte comme un tableau excepté que :
- le nombre d'élements du tuple est fixe
- le type des élements est connu
let skill: [string, number];
skill = ['Programming', 5];
Depuis TypeScript 3.0, un tuple peut avoir des élements optionneles en utilisant (?) :
let bgColor, headerColor: [number, number, number, number?];
bgColor = [0, 255, 255, 0.5];
headerColor = [0, 255, 255];
Type Enum
The following example creates an enum that represents the months of the year:
enum Month {
Jan = 1, // 1 au lieu de 0
Feb, // donc 2 au lieu de 1
Mar,
Apr,
May,
Jun,
Jul,
Aug,
Sep,
Oct,
Nov,
Dec
};
On peut utiliser cet enum ainsi :
function isItSummer(month: Month) {
let isSummer: boolean;
switch (month) {
case Month.Jun:
case Month.Jul:
case Month.Aug:
isSummer = true;
break;
default:
isSummer = false;
break;
}
return isSummer;
}
Type any
Pour manipuler une valeur dont on ne connait pas le type à la compilation, on peut utiliser le type any. Ainsi si on déclare une variable sans la typer, TypeScript assume l'utilisation du type any :
// json may come from a third-party API
const json = `{"latitude": 10.11, "longitude":12.12}`;
// parse JSON to find location
const currentLocation = JSON.parse(json);
console.log(currentLocation);
Code language: JavaScript (javascript)
Output:
{ latitude: 10.11, longitude: 12.12 }
Le type any permet de migrer gentiment vers le typage statique.
Type void
Le type void est utilisé pour spécifier l'absence complète de type, comme un méthode qui ne retourne rien.
Type never
Ne contient aucune valeur
Est utilisé pour les méthodes qui provoquent une erreur ou ne retourne jamais (boucle infinie par ex).
Type union
Ce type permet de combiner plusieurs types en un seul. Par exemple la variable suivante peut etre un nombre ou une chaine de caractères :
let result: number | string;
result = 10; // OK
result = 'Hi'; // also OK
result = false; // a boolean value, not OK
Utilisation pour les paramètres d'une mthode :
function add(a: number | string, b: number | string) {
if (typeof a === 'number' && typeof b === 'number') {
return a + b;
}
if (typeof a === 'string' && typeof b === 'string') {
return a.concat(b);
}
throw new Error('Parameters must be numbers or strings');
}
Type alias
Ce type permet de déclarer un nouveau nom pour un type :
type chars = string;
let messsage: chars; // same as string type
C'est particulièrement utile dans le cadre du type union :
type alphanumeric = string | number;
let input: alphanumeric;
input = 100; // valid
input = 'Hi'; // valid
input = false; // Compiler error
Type Chaine de Caractères littérale
Le type "string literal" permet de limiter les valeurs que peut prendre une chaine de caractères :
let click: 'click';
click = 'click'; // valid
click = 'dblclick'; // compiler error
Ce type est pratique notamment lorsqu'il est utilisé avec le type union et le type alias :
type MouseEvent: 'click' | 'dblclick' | 'mouseup' | 'mousedown';
let mouseEvent: MouseEvent;
mouseEvent = 'click'; // valid
mouseEvent = 'dblclick'; // valid
mouseEvent = 'mouseup'; // valid
mouseEvent = 'mousedown'; // valid
mouseEvent = 'mouseover'; // compiler error
Instructions conditionnelles
if(condition) {
// if-statement
}
if(condition) {
// if-statements
} else {
// else statements;
}
const max = 100;
let counter = 100;
counter < max ? counter++ : counter = 1;
console.log(counter);
let discount: number;
let itemCount = 11;
if (itemCount > 0 && itemCount <= 5) {
discount = 5; // 5% discount
} else if (itemCount > 5 && itemCount <= 10) {
discount = 10; // 10% discount
} else {
discount = 15; // 15%
}
switch ( expression ) {
case value1:
// statement 1
break;
case value2:
// statement 2
break;
case valueN:
// statement N
break;
default:
//
break;
}
for(initialization; condition; expression) {
// statement
}
Bloc optionnels :
let i = 0;
for (; i < 10; i++) {
console.log(i);
}
Like the initialization block, you can omit the condition block.
However, you must escape the loop when a condition is met by using the if and break statements. Otherwise, you will create an infinite loop that causes the program to executes repeatedly until it is crashed.
for (let i = 0; ; i++) {
console.log(i);
if (i > 9) break;
}
The following example illustrates a for loop that omits all three blocks:
let i = 0;
for (; ;) {
console.log(i);
i++;
if (i > 9) break;
}
Boucle while
let counter = 0;
while (counter < 5) {
console.log(counter);
counter++;
}
Boucle do...while
do {
// do something
} while(condition);
Les boucles ou switch peuvent être interrompues avace l'instruction "break". L'itération courante peut également être "ignorée" avec l'instruction "continue".
Exemple :
let index = -1;
while (index < 9) {
index = index + 1;
if (index % 2)
continue;
console.log(index);
}
Output:
0
2
4
6
8
Ressources :
- https://www.typescripttutorial.net/
- https://www.javascripttutorial.net/es-next/
Commentaires
Enregistrer un commentaire