TypeScript
Un langage de programmation qui ajoute un typage statique à JavaScript, améliorant la robustesse et la maintenabilité du code.
Qu'est-ce que TypeScript ?
Si JavaScript est comme écrire des instructions sur un post-it, TypeScript est comme rédiger un contrat détaillé. Il ajoute des règles et des garanties au JavaScript pour éviter les erreurs courantes.
TypeScript a été créé par Microsoft en 2012 pour résoudre un problème majeur : développer des applications JavaScript volumineuses devenait difficile à maintenir et sujet aux erreurs.
Pourquoi TypeScript est important ?
Fiabilité améliorée
TypeScript attrape les erreurs avant même que le code ne s'exécute, évitant ainsi de nombreux bugs en production.
Productivité
Les outils comprennent mieux votre code, offrant une auto-complétion intelligente et des suggestions précises.
En résumé, TypeScript est comme un assistant vigilant qui vérifie votre travail à chaque étape. Il permet aux équipes de développer des applications plus rapidement et avec moins d'erreurs, tout en rendant le code plus facile à comprendre et à maintenir.
Fonctionnement technique
TypeScript est un sur-ensemble typé de JavaScript qui se compile en JavaScript pur. Il ajoute une couche de typage statique optionnel, permettant de détecter et prévenir des erreurs lors de la phase de compilation plutôt qu'à l'exécution.
Les concepts fondamentaux
Types de base
TypeScript offre une large gamme de types primitifs et composés, permettant de décrire précisément les structures de données utilisées dans votre application.
// Types de base en TypeScript
let isDone: boolean = false;
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
let color: string = "blue";
let fullName: string = `Bob Bobbington`;
let age: number = 37;
let sentence: string = `Hello, my name is ${fullName}.
I'll be ${age + 1} years old next month.`;
// Arrays
let list: number[] = [1, 2, 3];
let list2: Array<number> = [1, 2, 3]; // Syntaxe générique
// Tuples
let x: [string, number] = ["hello", 10];
// Enum
enum Color {Red, Green, Blue}
let c: Color = Color.Green; // 1
// Any
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // OK, définitivement un boolean
Interfaces
Les interfaces définissent des contrats dans votre code et fournissent des noms explicites aux types d'objets. Elles permettent de décrire la forme exacte d'un objet ou d'une fonction.
// Interface définissant la structure d'un objet
interface User {
id: number;
name: string;
email: string;
isActive: boolean;
// Propriété optionnelle
phone?: string;
// Propriété en lecture seule
readonly createdAt: Date;
}
// Utilisation de l'interface
function createUser(user: User): User {
// Création d'un nouvel utilisateur
return {
...user,
isActive: true,
createdAt: new Date()
};
}
const newUser = createUser({
id: 1,
name: "John Doe",
email: "john@example.com",
createdAt: new Date()
});
// Interface pour décrire une fonction
interface SearchFunc {
(source: string, subString: string): boolean;
}
// Implémentation de l'interface de fonction
const mySearch: SearchFunc = function(src, sub) {
return src.search(sub) > -1;
};
Classes
TypeScript implémente pleinement la programmation orientée objet avec des classes, incluant l'héritage, les modificateurs d'accès, les getters/setters, et plus encore.
// Classe avec propriétés typées
class Person {
// Propriétés privées
private _age: number;
// Propriété protégée
protected name: string;
// Propriété publique avec type explicite
public readonly id: number;
// Constructeur avec paramètres typés
constructor(name: string, age: number, id: number) {
this.name = name;
this._age = age;
this.id = id;
}
// Getter avec type de retour
get age(): number {
return this._age;
}
// Setter
set age(value: number) {
if (value < 0 || value > 120) {
throw new Error("Age must be between 0 and 120");
}
this._age = value;
}
// Méthode avec type de retour
greet(): string {
return `Hello, my name is ${this.name} and I'm ${this._age} years old.`;
}
}
// Héritage de classe
class Employee extends Person {
// Nouvelle propriété
private department: string;
constructor(name: string, age: number, id: number, department: string) {
// Appel du constructeur parent
super(name, age, id);
this.department = department;
}
// Surcharge de méthode
greet(): string {
return `${super.greet()} I work in ${this.department}.`;
}
}
// Création d'instances
const john = new Employee("John", 32, 1, "Engineering");
console.log(john.greet());
Génériques
Les génériques permettent de créer des composants réutilisables qui peuvent fonctionner avec une variété de types, tout en préservant la sécurité du typage.
// Fonction générique
function identity<T>(arg: T): T {
return arg;
}
// Utilisation explicite
let output = identity<string>("myString");
// Utilisation avec inférence de type
let output2 = identity(42); // type: number
// Interface générique
interface GenericIdentityFn<T> {
(arg: T): T;
}
// Implémentation d'interface générique
let myIdentity: GenericIdentityFn<number> = identity;
// Classe générique
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
// Instance avec le type number
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };
// Utilisation de contraintes
interface Lengthwise {
length: number;
}
// T doit avoir une propriété length
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length); // Now we know it has a .length property
return arg;
}
// Fonctionne avec les strings, arrays, et tout type ayant une propriété length
loggingIdentity("hello");
loggingIdentity([1, 2, 3]);
Avantages techniques
- Détection d'erreurs anticipée grâce au typage statique et à l'analyse de code
- Refactoring sécurisé avec une meilleure détection des changements impactants
- Documentation intégrée via les annotations de type qui servent de documentation vivante
- Meilleure intégration IDE avec auto-complétion, navigation de code et refactoring intelligent
- Évolutivité améliorée pour les bases de code importantes et les équipes nombreuses
Fonctionnalités avancées
TypeScript propose également des fonctionnalités avancées qui permettent de modéliser des systèmes de types complexes et d'exprimer des patterns sophistiqués.
// Types utilitaires
type Partial<T> = { [P in keyof T]?: T[P] };
type Required<T> = { [P in keyof T]-?: T[P] };
type Readonly<T> = { readonly [P in keyof T]: T[P] };
type Pick<T, K extends keyof T> = { [P in K]: T[P] };
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
// Exemple d'utilisation
interface Todo {
title: string;
description: string;
completed: boolean;
createdAt: number;
}
// Partial: toutes les propriétés sont optionnelles
type TodoPartial = Partial<Todo>;
const updateTodo = (todo: Todo, fieldsToUpdate: TodoPartial): Todo => {
return { ...todo, ...fieldsToUpdate };
};
// Readonly: toutes les propriétés en lecture seule
type ReadonlyTodo = Readonly<Todo>;
const todo: ReadonlyTodo = {
title: "Delete inactive users",
description: "...",
completed: false,
createdAt: Date.now()
};
// Omit: exclut les propriétés spécifiées
type TodoPreview = Omit<Todo, "createdAt">;
const preview: TodoPreview = {
title: "Clean room",
description: "...",
completed: false
};
// Union de types littéraux
type Status = "pending" | "inProgress" | "completed" | "failed";
// Intersection de types
type Admin = {
name: string;
privileges: string[];
};
type Employee = {
name: string;
startDate: Date;
};
type ElevatedEmployee = Admin & Employee;
Cas d'usage
Applications d'entreprise
Idéal pour les applications métier complexes nécessitant une grande fiabilité, une maintenance à long terme et une évolution constante.
Frameworks et librairies
Utilisé avec des frameworks comme Angular, React ou Vue pour créer des applications web robustes avec moins de bugs.
Backend avec Node.js
Développement d'API et de services backend avec TypeScript et Node.js pour une architecture plus sûre et maintenable.
Migration progressive
Parfait pour moderniser des applications JavaScript existantes en adoptant TypeScript progressivement, fichier par fichier.
Entreprises qui utilisent TypeScript
De nombreuses entreprises de premier plan ont adopté TypeScript pour leurs produits et services: