Introduction à TypeScript
TypeScript est un langage de programmation développé par Microsoft qui étend JavaScript en ajoutant des types statiques. TypeScript est compilé en JavaScript et est compatible avec tous les environnements JavaScript. TypeScript aide à détecter les erreurs tôt, améliore l'autocomplétion, et rend le code plus maintenable.
📘 Qu'est-ce que TypeScript ?
TypeScript est un sur-ensemble de JavaScript qui ajoute des types statiques. TypeScript est compilé en JavaScript standard et est 100% compatible avec JavaScript.
💡 Pourquoi TypeScript est si populaire ?
- Types statiques - Détection d'erreurs à la compilation
- Meilleure autocomplétion - IDE plus intelligent
- Refactoring sûr - Modifications de code plus sûres
- Adopté par les grandes entreprises - Google, Microsoft, Facebook
- Frameworks modernes - React, Vue.js, Angular utilisent TypeScript
- Croissance rapide - Un des langages qui croît le plus vite
🚀 Pourquoi apprendre TypeScript ?
TypeScript offre de nombreux avantages :
- ✅ JavaScript amélioré - Tous les avantages de JavaScript + types
- ✅ Moins d'erreurs - Détection d'erreurs avant l'exécution
- ✅ Meilleure productivité - Autocomplétion et refactoring
- ✅ Très demandé - Forte demande sur le marché
- ✅ Frameworks modernes - React, Vue.js, Angular
- ✅ Grandes équipes - Idéal pour les projets d'équipe
📋 Prérequis pour apprendre TypeScript
Pour apprendre TypeScript efficacement, il est recommandé d'avoir :
- ✅ Connaissances JavaScript - Bases solides en JavaScript
- ✅ Node.js - Pour installer TypeScript
- ✅ Éditeur de code - VS Code recommandé (support TypeScript intégré)
💡 Note importante : TypeScript nécessite Node.js. Installez TypeScript avec npm install -g typescript. VS Code offre un excellent support TypeScript avec autocomplétion et vérification de types.
🎯 Cas d'usage de TypeScript
TypeScript est utilisé pour :
- Applications web - React, Vue.js, Angular avec TypeScript
- Applications Node.js - Backend avec Express, NestJS
- Applications mobiles - React Native, Ionic
- Outils de développement - Outils et CLI
- Projets d'équipe - Meilleure collaboration
- Applications complexes - Projets de grande envergure
📝 Syntaxe de base
TypeScript utilise la même syntaxe que JavaScript mais avec l'ajout de types. Les types sont optionnels mais recommandés.
// Premier programme TypeScript
console.log("Bonjour, monde !");
// Variables avec types
let nom: string = "NiangProgrammeur";
let age: number = 25;
// Template literals pour formater les chaînes
console.log(`Je m'appelle ${nom} et j'ai ${age} ans`);
// Opérations simples
let resultat: number = 10 + 5;
console.log(`10 + 5 = ${resultat}`);
💡 Points importants sur TypeScript :
- Même syntaxe que JavaScript
- Types optionnels - Vous pouvez utiliser TypeScript comme JavaScript
- Inférence de type - TypeScript peut déduire les types
- Compilation - TypeScript est compilé en JavaScript
- Fichiers .ts - Extension .ts pour les fichiers TypeScript
🔍 Exemple de code TypeScript
Voici un exemple montrant la syntaxe de base de TypeScript :
// Définition d'une fonction
function calculerMoyenne(nombres: number[]): number {
// Calcule la moyenne d'un tableau de nombres
if (nombres.length === 0) {
return 0;
}
const somme = nombres.reduce((acc, val) => acc + val, 0);
const moyenne = somme / nombres.length;
return moyenne;
}
// Utilisation
const notes: number[] = [15, 18, 12, 20, 16];
const moyenne = calculerMoyenne(notes);
console.log(`La moyenne est : ${moyenne}`);
🔤 Types de base
TypeScript propose plusieurs types : string, number, boolean, array, object, etc.
// Déclaration de variables avec types
let nom: string = "TypeScript"; // String (chaîne de caractères)
let age: number = 30; // Number (entier ou décimal)
let prix: number = 19.99; // Number (nombre décimal)
let estActif: boolean = true; // Boolean (booléen)
let valeurNulle: null = null; // null (valeur nulle)
let valeurUndefined: undefined = undefined; // undefined
// Affichage
console.log(nom);
console.log(age);
console.log(prix);
console.log(estActif);
console.log(valeurNulle);
// Réassignation (même type)
let variable: number = 10;
console.log(typeof variable); // "number"
// variable = "Dix"; // Erreur : type incompatible
// Noms de variables valides (camelCase)
let nomUtilisateur: string = "Bassirou";
let ageUtilisateur: number = 25;
let _prive: string = "variable privée";
const CONSTANTE: number = 3.14159; // Constante
📌 Types TypeScript :
string- Chaînes de caractèresnumber- Nombres (entiers et décimaux)boolean- Booléens (true/false)array- Tableaux typésobject- Objetsany- N'importe quel type
📊 Interfaces
Les interfaces définissent la structure des objets et permettent la vérification de type.
// Types de base
let texte: string = "Hello"; // String (chaîne de caractères)
let nombre: number = 42; // Number (entier)
let decimal: number = 3.14; // Number (nombre décimal)
let booleen: boolean = true; // Boolean (booléen)
let valeurNulle: null = null; // null (valeur nulle)
let valeurUndefined: undefined = undefined; // undefined
// Collections (structures de données)
let liste: number[] = [1, 2, 3, 4, 5]; // Array (tableau ordonné, modifiable)
let tuple: [number, number, number] = [1, 2, 3]; // Tuple (tableau à taille fixe)
let dictionnaire: { nom: string; age: number } = { nom: "TypeScript", age: 30 }; // Object (paires clé-valeur)
let ensemble: Set<number> = new Set([1, 2, 3, 4]); // Set (ensemble unique, non ordonné)
// Vérifier le type
console.log(typeof texte); // "string"
console.log(typeof nombre); // "number"
console.log(Array.isArray(liste)); // true
console.log(typeof dictionnaire); // "object"
// Conversion de types
let ageStr: string = String(25); // Convertir en string
let ageInt: number = parseInt("25", 10); // Convertir en entier
let prixFloat: number = parseFloat("19.99"); // Convertir en décimal
📚 Types de données TypeScript :
- string - Chaînes de caractères
- number - Nombres (entiers et décimaux)
- boolean - Booléens (true/false)
- array - Tableaux typés (type[])
- object - Objets avec structure définie
- any - N'importe quel type (à éviter)
- void - Absence de valeur de retour
- null / undefined - Valeurs nulles
- tuple - Tableaux à taille fixe
- enum - Énumérations de constantes
🔢 Classes
TypeScript supporte les classes avec types, héritage, et modificateurs d'accès.
// Opérateurs arithmétiques
let a: number = 10;
let b: number = 3;
console.log(a + b); // Addition: 13
console.log(a - b); // Soustraction: 7
console.log(a * b); // Multiplication: 30
console.log(a / b); // Division: 3.3333333333333335
console.log(Math.floor(a / b)); // Division entière: 3
console.log(a % b); // Modulo (reste): 1
console.log(Math.pow(a, b)); // Puissance: 1000
// Opérateurs de comparaison
console.log(a > b); // true (supérieur à)
console.log(a < b); // false (inférieur à)
console.log(a >= b); // true (supérieur ou égal)
console.log(a <= b); // false (inférieur ou égal)
console.log(a === b); // false (égalité stricte)
console.log(a !== b); // true (différent)
// Opérateurs logiques
let x: boolean = true;
let y: boolean = false;
console.log(x && y); // false (ET logique)
console.log(x || y); // true (OU logique)
console.log(!x); // false (NON logique)
// Opérateurs d'assignation
let c: number = 5;
c += 3; // Équivalent à c = c + 3 (c devient 8)
c -= 2; // Équivalent à c = c - 2 (c devient 6)
c *= 2; // Équivalent à c = c * 2 (c devient 12)
c /= 3; // Équivalent à c = c / 3 (c devient 4)
// Comparaison d'objets
let liste1: number[] = [1, 2, 3];
let liste2: number[] = [1, 2, 3];
let liste3 = liste1;
console.log(liste1 === liste2); // false (références différentes)
console.log(liste1 === liste3); // true (même référence)
console.log(JSON.stringify(liste1) === JSON.stringify(liste2)); // true (valeurs égales)
🔀 Fonctions
Les fonctions peuvent avoir des types pour les paramètres et le retour.
// Structure if simple
let age: number = 20;
if (age >= 18) {
console.log("Vous êtes majeur");
} else {
console.log("Vous êtes mineur");
}
// Structure if/else if/else
let age2: number = 15;
if (age2 >= 18) {
console.log("Vous êtes majeur");
console.log("Vous pouvez voter");
} else if (age2 >= 13) {
console.log("Vous êtes adolescent");
} else if (age2 >= 6) {
console.log("Vous êtes enfant");
} else {
console.log("Vous êtes un bébé");
}
// Conditions multiples
let note: number = 85;
let mention: string;
if (note >= 90) {
mention = "Excellent";
} else if (note >= 80) {
mention = "Très bien";
} else if (note >= 70) {
mention = "Bien";
} else if (note >= 60) {
mention = "Assez bien";
} else {
mention = "Insuffisant";
}
console.log(`Votre mention : ${mention}`);
// Opérateur ternaire (expression conditionnelle)
let age3: number = 20;
let statut: string = age3 >= 18 ? "Majeur" : "Mineur";
console.log(statut);
// Conditions avec &&/||
let age4: number = 25;
let permis: boolean = true;
if (age4 >= 18 && permis) {
console.log("Vous pouvez conduire");
} else {
console.log("Vous ne pouvez pas conduire");
}
🔄 Génériques
Les génériques permettent de créer des composants réutilisables avec des types variables.
// Boucle for classique
for (let i = 0; i < 5; i++) {
console.log(i); // Affiche 0, 1, 2, 3, 4
}
// Boucle for avec début et fin
for (let i = 1; i <= 5; i++) {
console.log(i); // Affiche 1, 2, 3, 4, 5
}
// Boucle for avec pas
for (let i = 0; i < 10; i += 2) {
console.log(i); // Affiche 0, 2, 4, 6, 8
}
// Boucle for...of avec tableau
let fruits: string[] = ["pomme", "banane", "orange"];
for (let fruit of fruits) {
console.log(`J'aime les ${fruit}`);
}
// Boucle for...in avec index
let fruits2: string[] = ["pomme", "banane", "orange"];
for (let index in fruits2) {
console.log(`${index}: ${fruits2[index]}`);
}
// Boucle while
let compteur: number = 0;
while (compteur < 5) {
console.log(compteur);
compteur++;
}
// Boucle while avec break
let compteur2: number = 0;
while (true) {
console.log(compteur2);
compteur2++;
if (compteur2 >= 5) {
break; // Sortir de la boucle
}
}
// continue (passer à l'itération suivante)
for (let i = 0; i < 10; i++) {
if (i % 2 === 0) { // Si i est pair
continue; // Passer au suivant
}
console.log(i); // Affiche seulement les impairs: 1, 3, 5, 7, 9
}
// Boucle do...while
let compteur3: number = 0;
do {
console.log(compteur3);
compteur3++;
} while (compteur3 < 5);
⚙️ Enums
Les enums permettent de définir un ensemble de constantes nommées.
// Fonction simple (sans paramètres)
function direBonjour(): void {
console.log("Bonjour !");
}
direBonjour(); // Appel de la fonction
// Fonction avec paramètres
function saluer(nom: string): string {
return `Bonjour, ${nom} !`;
}
let message: string = saluer("TypeScript");
console.log(message); // "Bonjour, TypeScript !"
// Fonction avec plusieurs paramètres
function additionner(a: number, b: number): number {
return a + b;
}
let resultat: number = additionner(5, 3);
console.log(resultat); // 8
// Fonction avec paramètres par défaut
function saluerPersonne(nom: string, message: string = "Bonjour"): string {
return `${message}, ${nom} !`;
}
console.log(saluerPersonne("Bassirou")); // "Bonjour, Bassirou !"
console.log(saluerPersonne("Bassirou", "Salut")); // "Salut, Bassirou !"
// Fonction avec paramètres nommés (via objet)
function creerPersonne({ nom, age, ville = "Dakar" }: { nom: string; age: number; ville?: string }): string {
return `${nom}, ${age} ans, habite à ${ville}`;
}
console.log(creerPersonne({ nom: "Bassirou", age: 25 }));
console.log(creerPersonne({ nom: "Bassirou", age: 25, ville: "Thiès" }));
// Fonction avec rest parameters (arguments variables)
function additionnerNombres(...args: number[]): number {
return args.reduce((acc, val) => acc + val, 0);
}
console.log(additionnerNombres(1, 2, 3, 4, 5)); // 15
// Fonction avec objet comme paramètre (équivalent **kwargs)
function afficherInfo(info: { nom: string; age: number; ville?: string }): void {
for (let cle in info) {
console.log(`${cle}: ${info[cle as keyof typeof info]}`);
}
}
afficherInfo({ nom: "Bassirou", age: 25, ville: "Dakar" });
// Fonction fléchée (arrow function)
const carre = (x: number): number => x * x;
console.log(carre(5)); // 25
// Utilisation de map() avec fonction fléchée
let nombres: number[] = [1, 2, 3, 4, 5];
let carres: number[] = nombres.map(x => x * x);
console.log(carres); // [1, 4, 9, 16, 25]
📋 Modules
TypeScript supporte les modules ES6 pour organiser le code.
// ========== ARRAYS ==========
// Création de tableaux
let nombres: number[] = [1, 2, 3, 4, 5];
let fruits: string[] = ["pomme", "banane", "orange"];
let listeMixte: (number | string | boolean)[] = [1, "deux", 3.0, true];
// Accès aux éléments (index commence à 0)
console.log(fruits[0]); // "pomme" (premier élément)
console.log(fruits[fruits.length - 1]); // "orange" (dernier élément)
// Modification
fruits[1] = "mangue"; // Remplacer "banane" par "mangue"
// Méthodes des tableaux
fruits.push("kiwi"); // Ajouter à la fin
fruits.splice(1, 0, "ananas"); // Insérer à l'index 1
let index = fruits.indexOf("pomme");
if (index > -1) fruits.splice(index, 1); // Supprimer un élément
fruits.pop(); // Supprimer le dernier élément
fruits.shift(); // Supprimer le premier élément
// Autres méthodes utiles
console.log(fruits.length); // Longueur du tableau
console.log(fruits.filter(f => f === "banane").length); // Compter les occurrences
fruits.sort(); // Trier le tableau
fruits.reverse(); // Inverser le tableau
// Slicing (tranches) avec slice()
let nombres2: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(nombres2.slice(2, 5)); // [2, 3, 4] (de l'index 2 à 4)
console.log(nombres2.slice(0, 3)); // [0, 1, 2] (du début à l'index 2)
console.log(nombres2.slice(3)); // [3, 4, 5, 6, 7, 8, 9] (de l'index 3 à la fin)
// ========== OBJECTS ==========
// Création d'objets
interface Personne {
nom: string;
age: number;
ville?: string;
email?: string;
}
let personne: Personne = {
nom: "Bassirou",
age: 25,
ville: "Dakar"
};
// Accès aux valeurs
console.log(personne.nom); // "Bassirou"
console.log(personne["age"]); // 25
console.log(personne.email || "Non renseigné"); // Valeur par défaut
// Modification et ajout
personne.age = 26; // Modifier
personne.email = "bassirou@example.com"; // Ajouter
// Méthodes des objets
console.log(Object.keys(personne)); // Toutes les clés
console.log(Object.values(personne)); // Toutes les valeurs
console.log(Object.entries(personne)); // Toutes les paires clé-valeur
// Parcourir un objet
for (let [cle, valeur] of Object.entries(personne)) {
console.log(`${cle}: ${valeur}`);
}
// Supprimer
delete personne.email; // Supprimer une propriété
📦 Décorateurs
Les décorateurs permettent d'ajouter des métadonnées aux classes, méthodes, et propriétés.
// Importer un module complet (ES6 modules)
import * as Math from 'math';
console.log(Math.sqrt(16)); // 4 (racine carrée)
console.log(Math.PI); // 3.141592653589793
console.log(Math.cos(0)); // 1
// Importer avec un alias
import * as dt from 'date-fns';
let maintenant = dt.now();
console.log(maintenant);
// Importer des fonctions spécifiques
import { sqrt, PI } from 'math';
console.log(sqrt(25)); // 5
console.log(PI); // 3.141592653589793
// Importer avec alias
import { sqrt as racineCarree } from 'math';
console.log(racineCarree(16)); // 4
// Modules standards utiles
// Math (built-in)
console.log(Math.random() * 100); // Nombre aléatoire entre 0 et 100
console.log(Math.floor(Math.random() * 100) + 1); // Entre 1 et 100
// Date (built-in)
let maintenant2 = new Date();
console.log(maintenant2);
// Créer son propre module
// Créer un fichier monModule.ts avec :
// export function maFonction(): string {
// return "Hello from module";
// }
//
// Puis l'importer :
// import { maFonction } from './monModule';
// console.log(maFonction());
// Export par défaut
// Dans monModule.ts :
// export default function maFonction() { ... }
//
// Import :
// import maFonction from './monModule';
🏗️ Intégration avec React
TypeScript s'intègre parfaitement avec React pour créer des composants typés.
// Définir une classe
class Personne {
// Propriétés de classe
nom: string;
age: number;
// Constructeur
constructor(nom: string, age: number) {
this.nom = nom; // Attribut d'instance
this.age = age;
}
// Méthode d'instance
sePresenter(): string {
return `Je m'appelle ${this.nom} et j'ai ${this.age} ans`;
}
avoirAns(annees: number): string {
this.age += annees;
return `Dans ${annees} ans, j'aurai ${this.age} ans`;
}
}
// Créer des objets (instances)
let personne1 = new Personne("Bassirou", 25);
let personne2 = new Personne("Aminata", 30);
// Utiliser les méthodes
console.log(personne1.sePresenter());
console.log(personne2.sePresenter());
console.log(personne1.avoirAns(5));
// Accéder aux attributs
console.log(personne1.nom);
console.log(personne1.age);
// Classe avec propriétés statiques
class Voiture {
// Propriété statique (partagée par toutes les instances)
static nombreVoitures: number = 0;
marque: string;
modele: string;
constructor(marque: string, modele: string) {
this.marque = marque;
this.modele = modele;
Voiture.nombreVoitures++;
}
toString(): string {
return `${this.marque} ${this.modele}`;
}
}
let voiture1 = new Voiture("Toyota", "Corolla");
let voiture2 = new Voiture("Honda", "Civic");
console.log(`Nombre de voitures créées : ${Voiture.nombreVoitures}`);
// Héritage
class Etudiant extends Personne {
ecole: string;
constructor(nom: string, age: number, ecole: string) {
super(nom, age); // Appeler le constructeur parent
this.ecole = ecole;
}
etudier(): string {
return `${this.nom} étudie à ${this.ecole}`;
}
}
let etudiant = new Etudiant("Bassirou", 25, "UCAD");
console.log(etudiant.sePresenter()); // Méthode héritée
console.log(etudiant.etudier()); // Méthode spécifique
📁 Bonnes pratiques
Utilisez les types strictement, évitez any, et utilisez les interfaces.
// Note: TypeScript/JavaScript côté client ne peut pas écrire dans des fichiers
// Pour Node.js (backend) :
// Écrire dans un fichier (mode 'w' = write)
import * as fs from 'fs';
fs.writeFileSync("fichier.txt", "Bonjour TypeScript !\nCeci est la deuxième ligne\n", "utf-8");
// Lire un fichier (mode 'r' = read)
let contenu: string = fs.readFileSync("fichier.txt", "utf-8");
console.log(contenu);
// Lire ligne par ligne
let lignes: string[] = fs.readFileSync("fichier.txt", "utf-8").split('\n');
lignes.forEach(ligne => {
console.log(ligne.trim()); // trim() enlève les espaces et sauts de ligne
});
// Ajouter à un fichier (mode 'a' = append)
fs.appendFileSync("fichier.txt", "Nouvelle ligne ajoutée\n", "utf-8");
// Méthodes asynchrones (recommandé)
fs.promises.writeFile("fichier.txt", "Contenu", "utf-8")
.then(() => console.log("Fichier écrit"))
.catch(err => console.error(err));
// Gestion d'erreurs
try {
let contenu2: string = fs.readFileSync("fichier_inexistant.txt", "utf-8");
} catch (error) {
if (error instanceof Error) {
console.error("Erreur:", error.message);
}
}
// Avec async/await (recommandé)
async function lireFichier(nomFichier: string): Promise {
try {
return await fs.promises.readFile(nomFichier, "utf-8");
} catch (error) {
if (error instanceof Error) {
console.error(`Erreur lors de la lecture: ${error.message}`);
}
throw error;
}
}
💡 Bonne pratique : Activez strict dans tsconfig.json pour une vérification de types plus stricte. Évitez any autant que possible.
🎓 Prochaines étapes
Félicitations ! Vous avez maintenant une solide base en TypeScript.
✅ Ce que vous avez appris :
- Types TypeScript de base
- Interfaces et types personnalisés
- Classes et héritage
- Fonctions typées
- Génériques
- Enums et unions
- Modules et imports
- Intégration avec React
🚀 Pour aller plus loin :
- TypeScript avancé - Utility types, mapped types
- React + TypeScript - Composants typés
- Vue.js + TypeScript - Composition API
- Node.js + TypeScript - Backend typé
- Testing - Tests avec TypeScript