1. Expliquez les types utilitaires TypeScript les plus importants.
TypeScript fournit des types utilitaires natifs puissants. Partial
2. Comment fonctionnent les generiques avances en TypeScript ?
Les generiques parametrent les types. Contraintes :
3. Qu'est-ce que le narrowing et les type guards en TypeScript ?
Le narrowing reduit un type large a un type plus specifique 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 verifier la presence d'une propriete. 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 ecrire 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 propriete : type Readonly
5. Comment typer les fonctions et les callbacks de maniere robuste ?
Function types : (arg: string) => number pour les signatures. Overloads : plusieurs signatures pour une fonction avec des comportements differents selon les parametres. Declaration overload + implementation : function parse(input: string): number; function parse(input: number): string; function parse(input: string | number) { ... }. Generiques pour les fonctions polymorphes : function first
6. Qu'est-ce que les declaration files (.d.ts) et le module augmentation ?
Les fichiers .d.ts declarent les types sans implementation. Utilisation : typer des bibliotheques JavaScript existantes (package @types/xxx sur DefinitelyTyped), declarer des modules ambiants (declare module 'mon-module'), typer des variables globales (declare global). Module augmentation : etendre les types d'un module existant. Exemple : ajouter une propriete a Express Request via declare module 'express' { interface Request { userId: string } }. Triple-slash directives pour les references entre fichiers de declaration. Le tsconfig.json configure les chemins de types avec typeRoots et types. Bonne pratique : creer un dossier types/ pour les declarations personnalisees du projet.
7. Comment gerer les enums et leurs alternatives en TypeScript ?
Les enums natifs : enum Direction { Up, Down } (numeriques, valeurs auto-incrementees) ou enum Status { Active = "active" } (string). Probleme des enums numeriques : pas de reverse lookup sur, ajout de valeurs peut casser le code existant. const enum : inline a 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 : preferer les unions de litteraux pour les nouveaux projets.
8. Expliquez le systeme de modules et la resolution en TypeScript.
TypeScript supporte ESM (import/export, standard) et CJS (require/module.exports, legacy Node). Le tsconfig controle 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 (meme pour les fichiers .ts) pour la compatibilite ESM stricte de Node.
9. Comment TypeScript gere-t-il les types pour les operations asynchrones ?
Promises : function fetchUser(): Promise
10. Quelles sont les bonnes pratiques TypeScript pour un projet en equipe ?
Configuration stricte : activer strict: true dans tsconfig (inclut strictNullChecks, noImplicitAny, etc.). noUncheckedIndexedAccess : les acces par index retournent T | undefined. Linting : eslint avec @typescript-eslint/recommended pour les regles specifiques TS. Eviter les any : preferer unknown quand le type est inconnu, les generiques pour la flexibilite. Interfaces vs Types : interfaces pour les objets extensibles (declaration merging), types pour les unions, intersections et types complexes. Immutabilite : Readonly