Nouveau : Datasets open source gratuits disponibles !Decouvrir →
🔷
Intermediaire 15 min TypeScript

Interfaces vs Types en TypeScript

Pourquoi Interfaces vs Types en TypeScript ?

Dans un environnement de développement moderne, les interfaces et les types jouent des rôles cruciaux pour la structure et la maintenance d'un code efficace et facile à comprendre. Les développeurs s'interrogent souvent sur les différences entre ces deux concepts et dans quel contexte utiliser chacun. Cette section explique pourquoi il est important de comprendre l'équivalence entre interfaces et types en TypeScript, ainsi qu'en pratique.

Contexte réel : Pourquoi un dev a besoin de cela au quotidien ?

En tant que développeur, vous devez souvent travailler sur des projets qui nécessitent une grande flexibilité et une évolutivité. Les interfaces et les types en TypeScript offrent une solution puissante pour gérer la structure et le comportement des objets dans votre code. Ils aident à définir les contrats d'API, à maintenir un code cohérent et à faciliter la collaboration entre équipes.

Un cas d'utilisation concret en 2-3 phrases

Imaginez que vous travaillez sur une application web où vous avez besoin de gérer des utilisateurs. Vous pourriez définir une interface User qui décrit les propriétés d'un utilisateur, comme son nom, son email et son âge. Ensuite, vous pouvez utiliser ce type dans votre code pour garantir que chaque objet utilisateur respecte le contrat défini.

Prerequis

Avant de commencer cet article, assurez-vous d'avoir les connaissances suivantes :

  • Connaissances en TypeScript
  • Compréhension des concepts de base comme les fonctions, les objets et la structure du code
  • Un environnement de développement configuré (Node.js recommandé)

Outils à installer

Pour démarrer ce tutoriel, vous aurez besoin d'installer les outils suivants :

  • Node.js (v14 ou plus)
  • npm (node package manager)
  • Code editor avec le support de TypeScript (VSCode recommandé)

Concepts fondamentaux

Interface

Une interface en TypeScript est un moyen de définir des types personnalisés qui peuvent être utilisés pour décrire la forme d'un objet. Elles permettent de spécifier les propriétés, méthodes et indexers qu'un objet doit avoir.

interface User {
  name: string;
  email: string;
  age?: number; // Propriété optionnelle avec un type par défaut
}

Type

Un type en TypeScript peut être utilisé pour définir des structures de données similaires à une interface, mais il offre également d'autres fonctionnalités. Par exemple, vous pouvez utiliser les types union et intersection pour combiner plusieurs types.

type Age = number | null;
type UserWithAge = { name: string; email: string } & { age?: Age };

Différences fondamentales

Bien que les interfaces et les types soient souvent utilisés de manière interchangeable, il existe des différences importantes à connaître :

  1. Inheritance : Les interfaces peuvent être étendues par d'autres interfaces avec le mot-clé extends, tandis que les types ne peuvent pas.
  2. Fusion : Vous pouvez fusionner plusieurs types ensemble avec l'opérateur &, mais vous ne pouvez pas faire la même chose avec les interfaces.
  3. Utilisation dans le code : Les interfaces sont généralement utilisées pour décrire les structures d'objets, tandis que les types peuvent être utilisés pour des cas de figure plus complexes comme les fonctions et les unions.

Mise en pratique : Projet fil rouge

Nous allons construire un gestionnaire de tâches simple avec une interface Task et un type TaskStatus. Ce projet comprendra la définition des types, la création d'une fonction pour ajouter une tâche et l'affichage des tâches.

Étape 1 : Définir les interfaces et types

Créez un fichier task.ts et définissez les structures de données nécessaires.

// task.ts
interface Task {
  id: number;
  title: string;
  description?: string;
  status: TaskStatus;
}

type TaskStatus = 'todo' | 'in-progress' | 'done';

Étape 2 : Créer un gestionnaire de tâches

Ajoutez une fonction pour ajouter des tâches et une fonction pour afficher les tâches.

// task.ts
import { Task, TaskStatus } from './task';

let taskIdCounter = 0;

function addTask(title: string, description?: string): Task {
  const newTask: Task = {
    id: ++taskIdCounter,
    title,
    description,
    status: 'todo'
  };
  tasks.push(newTask);
  return newTask;
}

function getTasks(): Task[] {
  return [...tasks];
}

const tasks: Task[] = [];

Étape 3 : Tester le gestionnaire de tâches

Ajoutez une fonction pour tester le gestionnaire de tâches.

// task.ts
import { addTask, getTasks } from './task';

function testTaskManager() {
  const task1 = addTask('Learn TypeScript');
  console.log(getTasks()); // [{ id: 1, title: 'Learn TypeScript', status: 'todo' }]
  
  const task2 = addTask('Build a project', 'Create a simple project using TypeScript');
  task2.status = 'in-progress';
  console.log(getTasks());
}

testTaskManager();

Structure des fichiers

Organisez votre code en plusieurs fichiers pour une meilleure lisibilité.

  • task.ts : Définition des interfaces et types.
  • main.ts : Code principal exécutant les tests.

Commandes à exécuter

Exécutez le fichier main.ts pour voir le résultat du gestionnaire de tâches.

tsc
node main.js

Erreurs fréquentes et debugging

Voici quelques erreurs courantes et comment les corriger :

Erreur 1 : Typo dans une propriété

Code incorrect :

const task = { id: 1, title: 'Learn TypeScript', statu: 'todo' };

Correction :

const task = { id: 1, title: 'Learn TypeScript', status: 'todo' };

Erreur 2 : Utilisation incorrecte d'un type

Code incorrect :

type Status = 'todo';
const taskStatus: Status = 'in-progress'; // Erreur de typage

Correction :

type Status = 'todo' | 'in-progress' | 'done';
const taskStatus: Status = 'in-progress'; // Correct

Erreur 3 : Manque d'initialisation

Code incorrect :

let taskIdCounter;
taskIdCounter++; // Erreur car taskIdCounter n'est pas initialisé

Correction :

let taskIdCounter = 0;
taskIdCounter++;

Pour aller plus loin

1. Types avancés

Explorez les types avancés comme les types génériques et les unions pour créer des structures de données réutilisables.

2. Interfaces avancées

Découvrez comment utiliser les interfaces avec la notation implements pour implémenter une interface dans une classe.

3. Union Types et Intersection Types

Explorez l'utilisation de union types (|) et intersection types (&) pour combiner plusieurs types ensemble de manière flexible.

Défi pratique

Implémentez un simple CRUD (Create, Read, Update, Delete) pour une liste d'utilisateurs en utilisant les interfaces et types. Créez des fichiers user.ts, userService.ts et main.ts.

N'oubliez pas, la pratique est la meilleure façon d'apprendre. Soyez curieux et n'hésitez pas à explorer ces concepts en profondeur!

Besoin d'aide sur TypeScript ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Quelle est la différence principale entre une interface et un type en TypeScript?
Une interface définit des signatures de méthodes ou de propriétés que les classes ou objets doivent implémenter. Un type peut être un alias pour n'importe quel type existant, y compris les types complexes comme les unions et les intersections.
Quelle est l'utilité des interfaces en TypeScript?
Les interfaces sont utiles pour définir la structure des objets et pour créer un contrat entre les classes ou fonctions. Elles permettent une meilleure organisation du code et facilitent la maintenance et le refactoring.
Comment utiliser une interface dans TypeScript?
Pour utiliser une interface, vous devez la déclarer en premier avec l'keyword `interface`. Ensuite, vous pouvez l'implémenter dans une classe en utilisant le mot-clé `implements`. Les classes qui implémentent une interface doivent fournir des définitions pour toutes les propriétés et méthodes définies dans l'interface.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.