Sommaire
- Introduction à TypeScript
- Qu’est-ce que TypeScript ?
- Pourquoi utiliser TypeScript ?
- Installation et configuration
- Compilation (tsc)
- Bases du Langage
- Types primitifs (string, number, boolean, null, undefined, symbol, bigint)
- Annotations de type
- Inférence de type
- Variables et constantes
- Opérateurs
- Structures de contrôle
- Fonctions
- Types Avancés
- Tableaux et Tuples
- Enums
- Any, Unknown, Void, Never
- Union Types et Intersection Types
- Alias de type
- Interfaces
- Déclaration et utilisation des interfaces
- Interfaces pour les objets, fonctions, classes
- Extension d’interfaces
- Classes
- Déclaration et utilisation des classes
- Modificateurs d’accès (public, private, protected)
- Héritage
- Classes abstraites
- Génériques (Generics)
- Fonctions génériques
- Interfaces génériques
- Classes génériques
- Contraintes de type
- Modules
- Import et Export
- Espaces de noms (Namespaces)
- Décorateurs
- Utilisation des décorateurs
- Création de décorateurs
- Configuration du Compilateur (tsconfig.json)
- Options courantes
- Inclusion et exclusion de fichiers
- Intégration avec des Frameworks JavaScript
- React, Angular, Vue.js
- Node.js
- Tests en TypeScript
- Utilisation d’outils de test JavaScript (Jest, Mocha) avec TypeScript
- Bonnes Pratiques
- Conventions de nommage
- Gestion des erreurs
- Utilisation stricte des types
- Ressources et Communauté
- Documentation officielle
- Communautés en ligne
1. Introduction à TypeScript
Qu’est-ce que TypeScript ?
TypeScript est un sur-ensemble typé de JavaScript qui compile en JavaScript simple. Il ajoute des fonctionnalités de typage statique, de classes et d’interfaces à JavaScript, ce qui permet de développer des applications plus robustes et maintenables.
Pourquoi utiliser TypeScript ?
- Typage statique : Détection des erreurs de type à la compilation, ce qui réduit les erreurs à l’exécution.
- Meilleure maintenabilité : Le typage statique facilite la compréhension et la refactorisation du code.
- Productivité accrue : L’autocomplétion et la vérification de type améliorent la productivité des développeurs.
- Compatibilité avec JavaScript : TypeScript compile en JavaScript simple, ce qui le rend compatible avec tous les navigateurs et environnements JavaScript.
Installation et configuration
- Installer Node.js et npm.
- Installer TypeScript globalement avec npm :
npm install -g typescript
.
Compilation (tsc)
- Utilisation du compilateur
tsc
pour compiler les fichiers TypeScript (.ts
) en fichiers JavaScript (.js
). - Commande de base :
tsc nom_fichier.ts
.
tsc mon_fichier.ts
2. Bases du Langage
Types primitifs (string, number, boolean, null, undefined, symbol, bigint)
string
: Chaînes de caractères.number
: Nombres (entiers et flottants).boolean
: Booléens (true ou false).null
: Absence de valeur intentionnelle.undefined
: Variable non initialisée.symbol
(ES6) : Identificateur unique.bigint
(ES2020) : Entiers de taille arbitraire.
let nom: string = "John";
let age: number = 30;
let estValide: boolean = true;
let valeurNull: null = null;
let valeurIndefinie: undefined = undefined;
let symbole: symbol = Symbol("description");
let grandNombre: bigint = 12345678901234567890n;
Annotations de type
- Permettent de spécifier le type d’une variable, d’un paramètre de fonction ou d’une valeur de retour.
- Syntaxe :
nom_variable: type
.
let nom: string = "John";
function add(a: number, b: number): number {
return a + b;
}
Inférence de type
- TypeScript peut inférer le type d’une variable à partir de sa valeur initiale.
let age = 30; // TypeScript infère que age est de type number
Variables et constantes
let
: Déclare une variable avec une portée de bloc.const
: Déclare une constante (valeur non modifiable).var
: Déclare une variable avec une portée de fonction (à éviter).
let age = 30;
const PI = 3.14159;
Opérateurs
- Arithmétiques :
+
,-
,*
,/
,%
,**
(exponentiation) - Relationnels :
==
,!=
,<
,>
,<=
,>=
- Logiques :
&&
,||
,!
- Affectation :
=
,+=
,-=
,*=
,/=
,%=
- Incrémentation/Décrémentation :
++
,--
- Comparaison stricte :
===
(valeur et type),!==
let x = 10;
let y = 5;
let sum = x + y;
let isEqual = (x == y);
let condition = (x > 0 && y < 10);
x++;
Structures de contrôle
if
,else if
,else
: Conditionnellesfor
,while
,do-while
: Bouclesswitch
: Sélection multiple
let score = 85;
if (score > 90) {
// ...
} else if (score > 80) {
// ...
} else {
// ...
}
for (let i = 0; i < 5; i++) {
// ...
}
while (score > 0) {
// ...
score--;
}
switch (score) {
case 100:
// ...
break;
default:
// ...
}
Fonctions
- Blocs de code réutilisables.
- Déclaration :
function nomFonction(paramètres: type): type_retour { // corps }
- Fonctions fléchées :
(paramètres: type) => type_retour { // corps }
function add(a: number, b: number): number {
return a + b;
}
let multiply = (a: number, b: number): number => {
return a * b;
}
console.log(add(5, 3));
console.log(multiply(5, 3));
3. Types Avancés
Tableaux et Tuples
- Tableaux : Collections ordonnées d’éléments du même type.
- Tuples : Collections ordonnées d’éléments de types différents (taille fixe).
let nombres: number[] = [1, 2, 3, 4, 5];
let personnes: string[] = ["Alice", "Bob", "Charlie"];
let coordonnees: [number, number] = [10, 20]; // Tuple
let personne: [string, number] = ["John", 30];
Enums
- Permettent de définir un ensemble de constantes nommées.
enum Couleur {
Rouge,
Vert,
Bleu
}
let couleurPreferee: Couleur = Couleur.Bleu;
Any, Unknown, Void, Never
any
: Type dynamique (désactive la vérification de type). À éviter autant que possible.unknown
: Type sûr pour représenter une valeur inconnue (nécessite un cast avant utilisation).void
: Indique qu’une fonction ne retourne aucune valeur.never
: Indique qu’une fonction ne termine jamais son exécution (ex: boucle infinie, exception).
let valeur: any = 10;
valeur = "Hello";
let valeurInconnue: unknown = "World";
// let longueur: number = valeurInconnue.length; // Erreur
let longueur: number = (valeurInconnue as string).length; // Cast
function afficherMessage(): void {
console.log("Message");
}
function erreur(): never {
throw new Error("Erreur");
}
Union Types et Intersection Types
- Union Types : Permettent de spécifier qu’une variable peut avoir plusieurs types possibles.
- Intersection Types : Permettent de combiner plusieurs types en un seul.
let resultat: string | number = "Hello";
resultat = 10;
interface A {
a: number;
}
interface B {
b: string;
}
type C = A & B; // Intersection type
let c: C = {
a: 10,
b: "Hello"
};
Alias de type
- Permettent de donner un nom à un type existant.
type Chaine = string;
let nom: Chaine = "John";
type Coordonnees = [number, number];
let point: Coordonnees = [10, 20];
4. Interfaces
Déclaration et utilisation des interfaces
- Une interface définit un contrat pour les objets, les fonctions et les classes.
- Elle spécifie les propriétés et les méthodes qu’un objet doit implémenter.
interface Personne {
nom: string;
age: number;
direBonjour(): void;
}
let personne: Personne = {
nom: "John",
age: 30,
direBonjour: function() {
console.log("Bonjour, je suis " + this.nom);
}
};
Interfaces pour les objets, fonctions, classes
- Les interfaces peuvent être utilisées pour définir la structure des objets, des fonctions et des classes.
// Interface pour un objet
interface Point {
x: number;
y: number;
}
// Interface pour une fonction
interface AddFunction {
(a: number, b: number): number;
}
let add: AddFunction = function(a: number, b: number): number {
return a + b;
}
// Interface pour une classe
interface Animal {
nom: string;
faireDuBruit(): void;
}
class Chien implements Animal {
nom: string;
constructor(nom: string) {
this.nom = nom;
}
faireDuBruit(): void {
console.log("Woof!");
}
}
Extension d’interfaces
- Une interface peut hériter des propriétés et des méthodes d’une autre interface.
interface A {
a: number;
}
interface B extends A {
b: string;
}
let b: B = {
a: 10,
b: "Hello"
};
5. Classes
Déclaration et utilisation des classes
- Utilisation du mot-clé
class
pour définir une classe. - Constructeur : méthode spéciale
constructor
. - Utilisation du mot-clé
this
pour référencer l’objet courant.
class Personne {
nom: string;
age: number;
constructor(nom: string, age: number) {
this.nom = nom;
this.age = age;
}
direBonjour(): void {
console.log("Bonjour, je suis " + this.nom);
}
}
let personne = new Personne("John", 30);
personne.direBonjour();
Modificateurs d’accès (public, private, protected)
public
: Accessible depuis n’importe où (par défaut).private
: Accessible uniquement depuis la classe où il est défini.protected
: Accessible depuis la classe où il est défini et depuis ses sous-classes.
class MaClasse {
public attributPublic: string = "Public";
private attributPrive: string = "Prive";
protected attributProtege: string = "Protege";
public afficherAttributs(): void {
console.log(this.attributPublic);
console.log(this.attributPrive);
console.log(this.attributProtege);
}
}
let obj = new MaClasse();
console.log(obj.attributPublic); // Accessible
// console.log(obj.attributPrive); // Erreur : non accessible
Héritage
- Permet à une classe (sous-classe) d’hériter des propriétés et des méthodes d’une autre classe (super-classe).
- Utilisation du mot-clé
extends
.
class Animal {
nom: string;
constructor(nom: string) {
this.nom = nom;
}
faireDuBruit(): void {
console.log("Bruit générique");
}
}
class Chien extends Animal {
faireDuBruit(): void {
console.log("Woof!");
}
}
let chien = new Chien("Fido");
chien.faireDuBruit(); // Woof!
Classes abstraites
- Une classe abstraite ne peut pas être instanciée directement.
- Elle peut contenir des méthodes abstraites (sans implémentation).
- Les classes qui héritent d’une classe abstraite doivent implémenter toutes ses méthodes abstraites.
abstract class Forme {
abstract calculerAire(): number;
}
class Cercle extends Forme {
rayon: number;
constructor(rayon: number) {
super();
this.rayon = rayon
}
calculerAire(): number {
return Math.PI * this.rayon * this.rayon;
}
}
6. Génériques (Generics)
Fonctions génériques
- Les génériques permettent d’écrire des fonctions qui peuvent fonctionner avec différents types de données.
- Utilisation de la syntaxe
<T>
pour définir un type générique.
function identite<T>(arg: T): T {
return arg;
}
let valeurString: string = identite<string>("Hello");
let valeurNombre: number = identite<number>(10);
Interfaces génériques
- Les interfaces génériques permettent de définir des interfaces qui peuvent fonctionner avec différents types de données.
interface Resultat<T> {
valeur: T;
succes: boolean;
}
let resultatString: Resultat<string> = {
valeur: "Hello",
succes: true
};
let resultatNombre: Resultat<number> = {
valeur: 10,
succes: false
};
Classes génériques
- Les classes génériques permettent de définir des classes qui peuvent fonctionner avec différents types de données.
class Boite<T> {
valeur: T;
constructor(valeur: T) {
this.valeur = valeur;
}
getValeur(): T {
return this.valeur;
}
}
let boiteString = new Boite<string>("Hello");
let boiteNombre = new Boite<number>(10);
Contraintes de type
- Permettent de limiter les types de données qui peuvent être utilisés avec un générique.
interface AvecLongueur {
length: number;
}
function afficherLongueur<T extends AvecLongueur>(arg: T): number {
return arg.length;
}
console.log(afficherLongueur("Hello")); // 5
// console.log(afficherLongueur(10)); // Erreur : number n'a pas de propriété length
7. Modules
Import et Export
- Les modules permettent d’organiser le code en fichiers séparés et de réutiliser le code.
- Utilisation des mots-clés
import
etexport
.
// module.ts
export interface Personne {
nom: string;
age: number;
}
export function direBonjour(personne: Personne): void {
console.log("Bonjour, " + personne.nom);
}
// main.ts
import { Personne, direBonjour } from "./module";
let personne: Personne = {
nom: "John",
age: 30
};
direBonjour(personne);
Espaces de noms (Namespaces)
- Les espaces de noms permettent d’organiser le code en groupes logiques (dépréciés au profit des modules).
namespace MonEspaceDeNom {
export interface MaInterface {
// ...
}
}
8. Décorateurs
Utilisation des décorateurs
- Les décorateurs sont des fonctions qui modifient le comportement des classes, des méthodes, des propriétés ou des paramètres.
- Utilisation de la syntaxe
@decorateur
pour appliquer un décorateur.
Création de décorateurs
function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log("Appel de " + propertyKey + " avec les arguments: " + JSON.stringify(args));
const result = originalMethod.apply(this, args);
console.log("Résultat: " + result);
return result;
};
}
class MaClasse {
@log
add(a: number, b: number): number {
return a + b;
}
}
let obj = new MaClasse();
obj.add(5, 3);
9. Configuration du Compilateur (tsconfig.json)
Options courantes
compilerOptions
:target
: Version de JavaScript cible (ex: “ES5”, “ES6”, “ESNext”).module
: Système de modules utilisé (ex: “CommonJS”, “ESNext”).outDir
: Répertoire de sortie pour les fichiers JavaScript compilés.rootDir
: Répertoire racine des fichiers TypeScript.sourceMap
: Génère des fichiers source map pour faciliter le débogage.strict
: Active toutes les options de vérification de type strict.esModuleInterop
: Permet d’importer des modules CommonJS comme des modules ES.
Inclusion et exclusion de fichiers
include
: Liste des fichiers ou des motifs de fichiers à inclure dans la compilation.exclude
: Liste des fichiers ou des motifs de fichiers à exclure de la compilation.
{
"compilerOptions": {
"target": "ES6",
"module": "CommonJS",
"outDir": "./dist",
"rootDir": "./src",
"sourceMap": true,
"strict": true,
"esModuleInterop": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
10. Intégration avec des Frameworks JavaScript
React, Angular, Vue.js
- TypeScript peut être utilisé avec les frameworks JavaScript populaires tels que React, Angular et Vue.js.
- Des définitions de type (DefinitelyTyped) sont disponibles pour la plupart des bibliothèques JavaScript, ce qui permet de bénéficier de la vérification de type dans ces frameworks.
Node.js
- TypeScript peut être utilisé pour développer des applications Node.js côté serveur.
- Le code TypeScript est compilé en JavaScript avant d’être exécuté par Node.js.
11. Tests en TypeScript
Utilisation d’outils de test JavaScript (Jest, Mocha) avec TypeScript
- TypeScript peut être testé avec les mêmes outils que JavaScript (ex: Jest, Mocha).
- Il est nécessaire d’utiliser un transpileur (ex: ts-jest, ts-node) pour exécuter le code TypeScript dans l’environnement de test.
12. Bonnes Pratiques
Conventions de nommage
- Utiliser le camelCase pour les noms de variables et de fonctions.
- Utiliser le PascalCase pour les noms de classes et d’interfaces.
- Utiliser des noms clairs et descriptifs.
Gestion des erreurs
- Utiliser les blocs
try...catch
pour gérer les exceptions. - Utiliser des types stricts pour éviter les erreurs de type.
- Utiliser des outils de linting pour détecter les erreurs potentielles.
Utilisation stricte des types
- Activer l’option
strict
dans le fichiertsconfig.json
pour bénéficier d’une vérification de type plus rigoureuse.