Angular est écrit en TypeScript, pas en JavaScript. Bonne nouvelle pour toi : TypeScript, c'est du JavaScript avec le typage statique que tu connais déjà par cœur en C#. Tu pars avec une longueur d'avance.
interface et des signatures typées. Savoir les déchiffrer d'un coup d'œil — comme tu lis un DTO C# — c'est le réflexe de base.
JavaScript est dynamiquement typé : une variable peut contenir n'importe quoi, et les erreurs de type n'explosent qu'à l'exécution. TypeScript rajoute par-dessus un typage statique vérifié à la compilation — exactement la sécurité que te donne le compilateur C#. Tu écris les types, l'éditeur t'engueule avant même de lancer le code.
int x = "bonjour"; ne compile pas : le compilateur refuse. TypeScript fait la même chose pour JavaScript. La seule différence d'écriture : le type se met après le nom, séparé par deux-points. string nom en C# devient nom: string en TS. C'est le même contrat, juste l'ordre des mots qui change.
On annote une variable, un paramètre ou un retour de fonction avec : Type. Lis ce service minimal qui calcule une moyenne de mesures :
let nomPoste: string = 'Poste A'; // comme: string nomPoste = "Poste A";
let seuilMax: number = 12.5; // pas d'int/double : TOUT est number
let estActif: boolean = true; // comme: bool estActif
let mesures: number[] = [12.1, 12.4, 11.9]; // un tableau de number (≈ List<double>)
function moyenne(valeurs: number[]): number { // paramètre typé, retour typé
const total = valeurs.reduce((a, b) => a + b, 0);
return total / valeurs.length;
}
| TypeScript | Équivalent C# | Piège à connaître |
|---|---|---|
string | string | Identique |
number | int / double / decimal | Un seul type pour tout : pas de distinction entier / flottant |
boolean | bool | Le mot est en entier |
number[] | List<double> / double[] | Aussi écrit Array<number> |
any | ≈ dynamic | Désactive tout contrôle. À fuir. |
any, c'est la trappe d'évasion qui éteint TypeScript : la variable redevient du JavaScript sauvage, plus aucune vérification. Sur un ERP, un any qui traîne, c'est un bug qui attend. En revue, tu le signales. Quand un type est vraiment inconnu, le bon réflexe moderne est unknown (qui, lui, t'oblige à vérifier avant d'utiliser).
interface : la forme d'un objetUne interface décrit la forme d'un objet : quels champs, de quels types. C'est l'équivalent direct d'un DTO ou d'une interface/record C#.
interface PosteMesure {
id: number;
nom: string;
derniereValeur: number;
commentaire?: string; // le ? = champ OPTIONNEL (≈ string? nullable)
}
const posteA: PosteMesure = {
id: 1,
nom: 'Poste A — soudure',
derniereValeur: 12.4,
// commentaire omis : autorisé car optionnel
};
Si tu oublies un champ obligatoire, ou que tu mets un string là où un number est attendu, TypeScript refuse — avant l'exécution, dans ton éditeur.
PosteMesure seulement s'il hérite explicitement de ce type. En TypeScript, le typage est structurel (« duck typing ») : tout objet qui a la bonne forme (les bons champs aux bons types) est accepté comme PosteMesure, même s'il n'a jamais « déclaré » l'interface. La forme suffit. C'est plus souple, et ça surprend toujours les gens qui viennent de C#.
Tu peux dire à TypeScript « cette valeur est l'un de ces choix précis » avec une union (le |). Très utilisé pour les statuts :
type Statut = 'ok' | 'alerte' | 'hors-service';
let etat: Statut = 'ok'; // OK
etat = 'alerte'; // OK
etat = 'inconnu'; // ❌ erreur : pas dans la liste autorisée
Le plus proche en C# serait une enum, mais l'union de chaînes est plus légère et lisible : la liste des valeurs valides est écrite noir sur blanc dans le type. Tu en croiseras partout dans l'ERP.
<T> : tu connais déjàBonne nouvelle : les génériques TypeScript sont quasi identiques à ceux de C#. Le <T> est un type « paramètre » : tu écris une fonction (ou une classe) une fois, elle marche pour n'importe quel type sans perdre la sécurité.
// Renvoie le premier élément d'un tableau, quel que soit son type
function premier<T>(liste: T[]): T {
return liste[0];
}
const p = premier(postes); // T = PosteMesure → p est un PosteMesure
const n = premier([1, 2, 3]); // T = number → n est un number
T Premier<T>(List<T> liste) en C#. Même idée, même syntaxe à un détail près. Et Array<T> en TS, c'est ta List<T>. Tu n'apprends rien de neuf ici : tu retrouves un vieil ami. En Angular tu verras énormément de génériques — Observable<T>, Signal<T>, QueryRef<T> — et ce sera toujours la même logique : « un conteneur d'un certain type ».
interface, que signifie commentaire?: string ?premier<T>(liste: T[]): T plutôt que premier(liste: any[]): any ?: Type. Une interface décrit la forme d'un objet (≈ DTO), avec ? pour l'optionnel. Une union 'a' | 'b' liste les valeurs autorisées. Les génériques <T> sont identiques à C#. Piège : le typage TS est structurel (la forme suffit), pas nominal.
Documentation officielle TypeScript — Everyday Types. Lis « The primitives », « Object Types » et « Union Types ». Garde l'onglet ouvert : c'est ta référence pour les prochaines leçons.
interface à partir d'un schéma GraphQL, ou la différence concrète entre type et interface ? Demande-moi, ici, maintenant. C'est en creusant que ça rentre.