Types de base
Maîtrisez les types primitifs et fondamentaux
Types de base en TypeScript
TypeScript offre plusieurs types primitifs qui constituent la base du système de types. Comprendre ces types est essentiel pour bien utiliser TypeScript.
Types primitifs
1. string
Le type string
représente les chaînes de caractères :
let nom: string = "Alice";
let message: string = `Bonjour ${nom}`;
let description: string = 'Développeuse TypeScript';
// Template literals
let html: string = `
<div>
<h1>${nom}</h1>
<p>${description}</p>
</div>
`;
2. number
Le type number
représente tous les nombres (entiers et décimaux) :
let age: number = 25;
let prix: number = 19.99;
let hexadecimal: number = 0xf00d;
let binaire: number = 0b1010;
let octal: number = 0o744;
// Opérations mathématiques
let total: number = prix * 2;
let moyenne: number = (10 + 20 + 30) / 3;
3. boolean
Le type boolean
représente les valeurs vraies ou fausses :
let estActif: boolean = true;
let estComplete: boolean = false;
// Résultat d'expressions
let estMajeur: boolean = age >= 18;
let aAcces: boolean = estActif && estMajeur;
4. undefined et null
Ces types représentent l’absence de valeur :
let valeurIndefinie: undefined = undefined;
let valeurNulle: null = null;
// Souvent utilisés dans des unions
let optionnel: string | undefined = undefined;
let nullable: number | null = null;
Types composés
1. Array (Tableaux)
Il existe plusieurs façons de typer les tableaux :
// Syntaxe avec crochets
let nombres: number[] = [1, 2, 3, 4, 5];
let noms: string[] = ["Alice", "Bob", "Charlie"];
// Syntaxe générique
let scores: Array<number> = [95, 87, 92];
let utilisateurs: Array<string> = ["user1", "user2"];
// Tableau de types mixtes
let mixte: (string | number)[] = ["Alice", 25, "Bob", 30];
// Méthodes de tableau
nombres.push(6);
let premier: number = nombres[0];
let longueur: number = nombres.length;
2. Tuple
Les tuples permettent de définir un tableau avec un nombre fixe d’éléments de types spécifiques :
// Définition d'un tuple
let personne: [string, number] = ["Alice", 25];
let coordonnees: [number, number] = [10.5, 20.3];
// Accès aux éléments
let nom: string = personne[0];
let age: number = personne[1];
// Tuple avec types optionnels
let point: [number, number, number?] = [10, 20]; // z est optionnel
// Tuple avec rest elements
let donnees: [string, ...number[]] = ["Alice", 1, 2, 3, 4];
3. Object
Typage des objets avec des propriétés spécifiques :
// Objet simple
let utilisateur: { nom: string; age: number } = {
nom: "Alice",
age: 25
};
// Propriétés optionnelles
let produit: { nom: string; prix: number; description?: string } = {
nom: "Ordinateur",
prix: 999
};
// Propriétés en lecture seule
let config: { readonly apiUrl: string; timeout: number } = {
apiUrl: "https://api.example.com",
timeout: 5000
};
// config.apiUrl = "autre-url"; // ❌ Erreur : propriété en lecture seule
Types spéciaux
1. any
Le type any
désactive la vérification de type (à éviter autant que possible) :
let valeurInconnue: any = 42;
valeurInconnue = "maintenant c'est une string";
valeurInconnue = true;
valeurInconnue.foo.bar; // Aucune erreur, mais dangereux
2. unknown
Le type unknown
est plus sûr que any
:
let valeur: unknown = 42;
// Il faut vérifier le type avant utilisation
if (typeof valeur === "string") {
console.log(valeur.toUpperCase()); // OK
}
if (typeof valeur === "number") {
console.log(valeur.toFixed(2)); // OK
}
3. void
Le type void
indique qu’une fonction ne retourne rien :
function afficherMessage(message: string): void {
console.log(message);
// Pas de return ou return undefined
}
function traiterDonnees(): void {
// Logique de traitement
return; // OK
}
4. never
Le type never
représente des valeurs qui n’arrivent jamais :
// Fonction qui lance toujours une erreur
function lancerErreur(message: string): never {
throw new Error(message);
}
// Fonction avec boucle infinie
function boucleInfinie(): never {
while (true) {
// Code qui ne se termine jamais
}
}
// Utile dans les switch exhaustifs
function traiterType(valeur: string | number): string {
switch (typeof valeur) {
case "string":
return valeur.toUpperCase();
case "number":
return valeur.toString();
default:
// valeur est de type never ici
const exhaustiveCheck: never = valeur;
return exhaustiveCheck;
}
}
Union et intersection
1. Union Types
Permet à une variable d’avoir plusieurs types possibles :
let identifiant: string | number;
identifiant = "ABC123";
identifiant = 12345;
function formaterIdentifiant(id: string | number): string {
if (typeof id === "string") {
return id.toUpperCase();
} else {
return id.toString().padStart(6, "0");
}
}
// Union avec plusieurs types
let statut: "en_attente" | "en_cours" | "termine" | "annule";
statut = "en_cours"; // OK
// statut = "invalide"; // ❌ Erreur
2. Intersection Types
Combine plusieurs types en un seul :
type Personne = {
nom: string;
age: number;
};
type Employe = {
entreprise: string;
salaire: number;
};
// Intersection : doit avoir toutes les propriétés
type EmployePersonne = Personne & Employe;
let employe: EmployePersonne = {
nom: "Alice",
age: 30,
entreprise: "TechCorp",
salaire: 50000
};
Assertions de type
Parfois, vous savez mieux que TypeScript quel est le type d’une valeur :
// Assertion avec "as"
let valeur: unknown = "hello world";
let longueur: number = (valeur as string).length;
// Assertion avec angle brackets (non recommandé en JSX)
let longueur2: number = (<string>valeur).length;
// Assertion non-null
let element: HTMLElement | null = document.getElementById("mon-element");
let elementSur: HTMLElement = element!; // On affirme qu'il n'est pas null
Exemples pratiques
Fonction avec types multiples
function calculer(a: number, b: number, operation: "+" | "-" | "*" | "/"): number {
switch (operation) {
case "+":
return a + b;
case "-":
return a - b;
case "*":
return a * b;
case "/":
if (b === 0) {
throw new Error("Division par zéro");
}
return a / b;
default:
const exhaustiveCheck: never = operation;
throw new Error(`Opération non supportée: ${exhaustiveCheck}`);
}
}
let resultat: number = calculer(10, 5, "+"); // 15
Gestion des données utilisateur
type Utilisateur = {
id: number;
nom: string;
email: string;
age?: number;
actif: boolean;
};
function creerUtilisateur(donnees: Partial<Utilisateur>): Utilisateur {
return {
id: Math.random(),
nom: donnees.nom || "Anonyme",
email: donnees.email || "",
actif: donnees.actif ?? true,
...donnees
};
}
let nouvelUtilisateur: Utilisateur = creerUtilisateur({
nom: "Alice",
email: "alice@example.com"
});
Bonnes pratiques
- Préférez les types spécifiques à
any
- Utilisez
unknown
plutôt queany
quand possible - Définissez des types union pour les valeurs limitées
- Utilisez les assertions avec parcimonie et seulement quand nécessaire
- Préférez les interfaces pour les objets complexes
Prochaines étapes
Maintenant que vous maîtrisez les types de base, vous êtes prêt à explorer :
- Les interfaces et types avancés
- Les génériques
- Les classes et l’héritage
- Les modules et namespaces
Conseil : Commencez par utiliser les types de base dans vos projets existants. L’ajout progressif de types améliore immédiatement la qualité de votre code.
Commentaires
Les commentaires sont alimentés par GitHub Discussions
Connectez-vous avec GitHub pour participer à la discussion