0%
Types de base en TypeScript

Types de base

Maîtrisez les types primitifs et fondamentaux

10-15 min

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

  1. Préférez les types spécifiques à any
  2. Utilisez unknown plutôt que any quand possible
  3. Définissez des types union pour les valeurs limitées
  4. Utilisez les assertions avec parcimonie et seulement quand nécessaire
  5. 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

Lien copié !