1. Expliquez les types utilitaires TypeScript les plus importants.
TypeScript fournit des types utilitaires natifs puissants. Partial
2. Comment fonctionnent les génériques avances en TypeScript ?
Les génériques parametrent les types. Contraintes :
3. Qu'est-ce que le narrowing et les type guards en TypeScript ?
Le narrowing réduit un type large à un type plus spécifique dans un bloc de code. typeof : if (typeof x === "string") pour les primitifs. instanceof : if (x instanceof Date) pour les classes. in operator : if ("name" in obj) pour vérifier la présence d'une propriété. Discriminated unions : un champ commun (type, kind) distingue les variantes, et le switch sur ce champ narrow automatiquement. Custom type guards : function isUser(x: any): x is User retourne un predicat de type. Assertion functions : function assertIsUser(x: any): asserts x is User lance une erreur si ce n'est pas un User. Le narrowing est fondamental pour écrire du code TypeScript type-safe sans casts dangereux.
4. Expliquez les types conditionnels et les mapped types.
Les conditional types : T extends U ? X : Y evaluent un type selon une condition. Distributifs sur les unions : si T = A | B, alors T extends U ? X : Y devient (A extends U ? X : Y) | (B extends U ? X : Y). Utilisation avec infer pour extraire des sous-types. Les mapped types transforment chaque propriété : type Readonly
5. Comment typer les fonctions et les callbacks de manière robuste ?
Function types : (arg: string) => number pour les signatures. Overloads : plusieurs signatures pour une fonction avec des comportements différents selon les paramètres. Déclaration overload + implémentation : function parse(input: string): number; function parse(input: number): string; function parse(input: string | number) { ... }. Génériques pour les fonctions polymorphes : function first
6. Qu'est-ce que les déclaration files (.d.ts) et le module augmentation ?
Les fichiers .d.ts declarent les types sans implémentation. Utilisation : typer des bibliothèques JavaScript existantes (package @types/xxx sur DefinitelyTyped), déclarer des modules ambiants (declare module 'mon-module'), typer des variables globales (declare global). Module augmentation : étendre les types d'un module existant. Exemple : ajouter une propriété à Express Request via declare module 'express' { interface Request { userId: string } }. Triple-slash directives pour les références entre fichiers de déclaration. Le tsconfig.json configure les chemins de types avec typeRoots et types. Bonne pratique : créer un dossier types/ pour les déclarations personnalisées du projet.
7. Comment gérer les enums et leurs alternatives en TypeScript ?
Les enums natifs : enum Direction { Up, Down } (numériques, valeurs auto-incrementees) ou enum Status { Active = "active" } (string). Problème des enums numériques : pas de reverse lookup sur, ajout de valeurs peut casser le code existant. const enum : inline à la compilation, plus performant mais pas de reverse lookup. Alternatives preferees : les union de string literals : type Status = "active" | "inactive" | "pending" sont plus simples, plus sures, et mieux supportees par le tree-shaking. Les objets as const : const Direction = { Up: "up", Down: "down" } as const avec type Direction = typeof Direction[keyof typeof Direction] combinent valeurs runtime et types. Recommendation : préférer les unions de littéraux pour les nouveaux projets.
8. Expliquez le système de modules et la résolution en TypeScript.
TypeScript supporte ESM (import/export, standard) et CJS (require/module.exports, legacy Node). Le tsconfig contrôle la sortie avec module (ESNext, CommonJS, NodeNext) et moduleResolution (node, bundler, nodeNext). Path mapping : paths dans tsconfig pour les alias (@components/*). barrel files (index.ts) pour re-exporter depuis un dossier. Type-only imports : import type { User } from './types' n'emet rien en JS, clarifie l'intention. Depuis TS 5.0 : verbatimModuleSyntax remplace les anciens flags d'import type. Le mode NodeNext impose les extensions .js dans les imports (même pour les fichiers .ts) pour la compatibilité ESM stricte de Node.
9. Comment TypeScript gere-t-il les types pour les opérations asynchrones ?
Promises : function fetchUser(): Promise
10. Quelles sont les bonnes pratiques TypeScript pour un projet en équipe ?
Configuration stricte : activer strict: true dans tsconfig (inclut strictNullChecks, noImplicitAny, etc.). noUncheckedIndexedAccess : les accès par index retournent T | undefined. Linting : eslint avec @typescript-eslint/recommended pour les règles spécifiques TS. Éviter les any : préférer unknown quand le type est inconnu, les génériques pour la flexibilité. Interfaces vs Types : interfaces pour les objets extensibles (déclaration merging), types pour les unions, intersections et types complexes. Immutabilité : Readonly