Pourquoi TypeScript a conquis le développement web
Si tu dĂ©veloppes en JavaScript depuis un moment, tu as sĂ»rement dĂ©jĂ vĂ©cu ça : une erreur undefined is not a function en plein milieu de la nuit, une propriĂ©tĂ© mal orthographiĂ©e qui passe inaperçue jusqu’en production, ou un refactoring qui tourne au cauchemar parce que tu ne sais jamais quel type de donnĂ©e circule dans ta fonction. TypeScript rĂ©sout prĂ©cisĂ©ment ces problĂšmes â et c’est pourquoi il est devenu le standard incontournable du dĂ©veloppement web moderne.
TypeScript est un sur-ensemble typĂ© de JavaScript dĂ©veloppĂ© par Microsoft. ConcrĂštement, tout code JavaScript valide est aussi du TypeScript valide. La diffĂ©rence ? TypeScript ajoute un systĂšme de types qui te permet de dĂ©tecter les erreurs Ă la compilation plutĂŽt qu’Ă l’exĂ©cution. RĂ©sultat : des bugs rattrapĂ©s des heures (voire des jours) avant la mise en production.
Selon le Stack Overflow Survey 2025, TypeScript est utilisĂ© par plus de 60 % des dĂ©veloppeurs JavaScript et se classe dans le top 5 des langages les plus adoptĂ©s. Des gĂ©ants comme Google (Angular), Microsoft (VS Code), Airbnb et Asana l’ont adoptĂ© en standard. Ce n’est pas une mode â c’est l’Ă©volution naturelle de JavaScript.
Ce que TypeScript apporte à ton développement quotidien
Avant d’entrer dans le code, prenons le temps de comprendre pourquoi TypeScript change la donne dans un projet rĂ©el.
â Le problĂšme JavaScript nu
function calculatePrice(product, quantity) {
return product.price * quantity;
}
// Appels dangereux â aucun avertissement
calculatePrice(undefined, "deux"); // NaN silencieux
calculatePrice({ name: "Livre" }, 3); // NaN (price n'existe pas)
Ces bugs passent en production parce que JavaScript n’a aucun moyen de vĂ©rifier ce que tu lui passes. En Ă©quipe, c’est pire : tu ne sais jamais quelle forme a un objet, quelles propriĂ©tĂ©s sont optionnelles, et ce que retourne une fonction donnĂ©e.
â TypeScript rĂ©sout tout ça
interface Product {
name: string;
price: number;
inStock: boolean;
}
function calculatePrice(product: Product, quantity: number): number {
return product.price * quantity;
}
// â Erreur dĂ©tectĂ©e Ă la compilation :
// Argument of type 'undefined' is not assignable to parameter of type 'Product'
calculatePrice(undefined, "deux");
// â Erreur : 'price' manque dans l'objet
calculatePrice({ name: "Livre" }, 3);
TypeScript te signale l’erreur directement dans ton Ă©diteur, avant mĂȘme d’exĂ©cuter le code. Le gain de temps est considĂ©rable : des Ă©tudes estiment que TypeScript rĂ©duit les bugs de production de 15 Ă 20 %.
Les bases essentielles pour démarrer
Voici tout ce que tu dois savoir pour commencer Ă Ă©crire du TypeScript dĂšs aujourd’hui.
Installation et configuration
C’est aussi simple que deux commandes :
# Installation globale
npm install -g typescript
# Compiler un fichier
tsc mon-fichier.ts
Pour un projet, un fichier tsconfig.json te permet de configurer le compilateur :
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"strict": true,
"outDir": "./dist"
},
"include": ["src/**/*"]
}
L’option strict: true est celle qui te protĂšge le plus. Active-la dĂšs le dĂ©but â elle t’Ă©vitera des heures de dĂ©bogage.
Les types de base
// Types primitifs
let nom: string = "Alice";
let age: number = 28;
let estActif: boolean = true;
// Tableaux
let scores: number[] = [85, 92, 78];
let fruits: Array<string> = ["pomme", "banane"];
// Tuples (tableaux de longueur fixe)
let coordonnees: [number, number] = [12.5, 45.8];
// Unions : un type OU un autre
let identifiant: string | number;
identifiant = "ABC123"; // OK
identifiant = 42; // OK
identifiant = true; // â Erreur
// Les alias de types
type UserID = string | number;
let userId: UserID = "user_abc";
Les interfaces â ton outil le plus puissant
Les interfaces dĂ©crivent la forme d’un objet. C’est ce qui rend TypeScript si utile dans les projets rĂ©els :
interface User {
id: number;
email: string;
name: string;
phone?: string; // ? = optionnel
readonly createdAt: Date; // lecture seule
}
interface AdminUser extends User {
role: "admin" | "superadmin";
permissions: string[];
}
function greet(user: User): string {
return `Bonjour ${user.name} !`;
}
const alice: AdminUser = {
id: 1,
email: "alice@exemple.fr",
name: "Alice",
createdAt: new Date(),
role: "admin",
permissions: ["read", "write"]
};
console.log(greet(alice)); // Bonjour Alice !
Les types gĂ©nĂ©riques â la flexibilitĂ© sans perdre la sĂ©curitĂ©
Parfois tu as besoin d’une fonction qui fonctionne avec plusieurs types tout en gardant la sĂ©curitĂ© du typage. Les gĂ©nĂ©riques sont faits pour ça :
// Fonction gĂ©nĂ©rique â T est un paramĂštre de type
function firstElement<T>(arr: T[]): T | undefined {
return arr[0];
}
const first = firstElement([1, 2, 3]); // number
const firstStr = firstElement(["a", "b"]); // string
// TypeScript INFĂRE le type automatiquement
// Une classe générique
class Repository<T> {
private items: T[] = [];
add(item: T): void {
this.items.push(item);
}
getAll(): T[] {
return [...this.items];
}
}
const userRepo = new Repository<User>();
userRepo.add(alice); // TypeScript vérifie que c'est bien un User
Les utilitaires TypeScript intégrés
TypeScript fournit des types utilitaires qui Ă©vitent d’Ă©crire du code rĂ©pĂ©titif :
interface Product {
id: number;
name: string;
price: number;
description: string;
}
// Partial â rend toutes les propriĂ©tĂ©s optionnelles
function updateProduct(id: number, updates: Partial<Product>) {
// Parfait pour les PATCH API
}
// Pick â sĂ©lectionne certaines propriĂ©tĂ©s
type ProductSummary = Pick<Product, "id" | "name" | "price">;
// Omit â supprime certaines propriĂ©tĂ©s
type ProductInput = Omit<Product, "id">; // id en moins
// Record â dictionnaire typĂ©
const inventory: Record<string, number> = {
"pomme": 45,
"banane": 30
};
TypeScript en pratique : un exemple complet
Voici un mini-projet qui combine tout ce qu’on vient de voir â un gestionnaire de panier d’achat :
// types.ts
export interface Product {
id: string;
name: string;
price: number;
category: "food" | "electronics" | "clothing";
}
export interface CartItem {
product: Product;
quantity: number;
}
// cart.ts
export class ShoppingCart {
private items: CartItem[] = [];
addItem(product: Product, quantity: number = 1): void {
const existing = this.items.find(
item => item.product.id === product.id
);
if (existing) {
existing.quantity += quantity;
} else {
this.items.push({ product, quantity });
}
}
removeItem(productId: string): void {
this.items = this.items.filter(
item => item.product.id !== productId
);
}
getTotal(): number {
return this.items.reduce(
(total, item) => total + item.product.price * item.quantity,
0
);
}
getSummary(): string {
return this.items
.map(item => `${item.product.name} x ${item.quantity}`)
.join(", ");
}
}
// main.ts
const cart = new ShoppingCart();
const apple: Product = {
id: "p1",
name: "Pomme",
price: 1.50,
category: "food"
};
const phone: Product = {
id: "p2",
name: "Téléphone",
price: 299,
category: "electronics"
};
cart.addItem(apple, 3);
cart.addItem(phone, 1);
console.log(cart.getTotal()); // 303.50
console.log(cart.getSummary()); // "Pomme x 3, Téléphone x 1"
Ce gestionnaire est entiĂšrement typĂ© : impossible d’ajouter un objet sans le bon format, impossible de modifier une quantitĂ© par une chaĂźne de caractĂšres, et l’autocomplĂ©tion de ton IDE te guide Ă chaque Ă©tape.
Intégrer TypeScript dans un projet existant
Pas besoin de tout réécrire pour bénéficier de TypeScript. La migration est progressive :
- Renommer un fichier
.jsen.ts - Ajouter
// @ts-checken haut d’un fichier JS pour activer la vĂ©rification sans le convertir - Configurer
allowJs: truedanstsconfig.jsonpour cohabiter avec du JS legacy - Définir
strict: falsetemporairement, puis l’activer progressivement fichier par fichier - Utiliser des fichiers
.d.tspour décrire les types des bibliothÚques externes sans les modifier
React, Next.js, Vue 3, Svelte, NestJS â tous les frameworks modernes supportent TypeScript nativement. Quand tu crĂ©es un projet avec create-react-app ou create-next-app, ajoute simplement l’option --typescript.
Les piÚges à éviter quand tu débutes
MĂȘme avec TypeScript, certains piĂšges sont faciles Ă Ă©viter si tu les connais :
â ïž Le any â l’anti-type
Quand tu ne sais pas quel type utiliser, la tentation est grande d’Ă©crire any. ProblĂšme : any dĂ©sactive totalement la vĂ©rification de type. C’est comme ne pas porter ta ceinture de sĂ©curitĂ©. PrivilĂ©gie unknown (qui oblige Ă vĂ©rifier le type avant d’utiliser la valeur) ou un type union.
// à éviter
function process(data: any) {
return data.something; // Aucune vérification !
}
// Recommandé
function process(data: unknown) {
if (typeof data === "object" && data !== null && "something" in data) {
return (data as Record<string, unknown>).something;
}
return null;
}
â ïž L’infĂ©rence de type â ne surajoute pas des annotations
TypeScript infĂšre automatiquement le type d’une variable initialisĂ©e. Inutile d’Ă©crire :
// Redondant â TypeScript voit dĂ©jĂ que c'est un string
const message: string = "Bonjour";
// Parfait â l'infĂ©rence fait le travail
const message = "Bonjour";
â ïž as â le cast sauvage
Le mot-clĂ© as force un type. UtilisĂ© trop souvent, il vide TypeScript de son intĂ©rĂȘt. Ne l’utilise que quand tu ES certain du type et que TypeScript ne peut pas le dĂ©duire (par exemple avec JSON.parse).
Et aprÚs ? Passer à la vitesse supérieure
Une fois que tu maĂźtrises les bases de TypeScript, voici les prochains sujets Ă explorer :
- TypeScript avec React â les props typĂ©s, les hooks gĂ©nĂ©riques, les event handlers
- Les types conditionnels (
extends,infer) pour créer des types dynamiques - Les template literal types pour construire des types à partir de chaßnes
- Les décorateurs (utile avec Angular et NestJS)
TypeScript n’est pas une langue Ă©trangĂšre â c’est JavaScript avec des super-pouvoirs. Les premiers jours, le compilateur va te sembler exigeant, mais tu rĂ©aliseras vite que chaque erreur qu’il rattrape est un bug qui n’atteindra jamais tes utilisateurs.
Alors, prĂȘt Ă faire le saut ? Lance ton terminal, installe TypeScript, crĂ©e ton premier fichier .ts, et laisse le compilateur devenir ton meilleur alliĂ©.
Photo de Kevin Ku sur Pexels.