Nouveau : Datasets open source gratuits disponibles !Decouvrir →
🔷
Avance 30 min TypeScript

Les types avances en TypeScript

Pourquoi types avances en TypeScript ?

Dans un monde où les projets deviennent de plus en plus complexes, l'utilisation de TypeScript permet aux développeurs d'écrire du code plus robuste et maintenable. Les types avancés offrent des fonctionnalités qui aident à prévenir les bugs en amont, à augmenter la lisibilité du code et à assurer la cohérence des structures de données. Un cas concret est l'utilisation de génériques pour créer des composants réutilisables et types sécurisés, ou encore les interfaces étendues qui permettent d'ajouter de nouvelles propriétés à des objets existants.

Prerequis

  • Connaissance approfondie de TypeScript (pratiquement tout ce que vous avez appris jusqu'à présent)
  • Compréhension des concepts de base : types primitifs, objets, tableaux, fonctions
  • Familiarité avec les structures de contrôle avancées : boucles for...of, map, filter
  • Connaissance des interfaces et des classes en TypeScript

Outils à installer :

  • Node.js v14 ou supérieur
  • npm (Node Package Manager)
  • Visual Studio Code (ou n'importe quel éditeur de code moderne avec une bonne prise en charge de TypeScript)

Concepts fondamentaux

1. Génériques

Les génériques permettent aux fonctions et aux classes de travailler avec des types variables plutôt que des types fixes.

// ❌ Sans génériques
function identity(arg: any): any {
    return arg;
}

let output = identity("myString");

// ✅ Avec génériques
function identity<T>(arg: T): T {
    return arg;
}

let output = identity<string>("myString");

2. Interfaces étendues

Les interfaces étendues permettent de combiner les définitions d'interfaces existantes.

interface Animal {
    name: string;
}

interface Dog extends Animal {
    breed: string;
}

const myDog: Dog = {
    name: "Buddy",
    breed: "Golden Retriever"
};

3. Types unions et intersections

Les unions et les intersections permettent de combiner des types en fonction de vos besoins.

// Unions : Permet de spécifier plusieurs types possibles
type Status = "loading" | "success" | "error";

function logStatus(status: Status) {
    if (status === "loading") {
        console.log("Loading...");
    } else if (status === "success") {
        console.log("Success!");
    } else {
        console.error("Error occurred");
    }
}

// Intersections : Permet de combiner plusieurs types en un
interface A { a: string; }
interface B { b: number; }

type AB = A & B;

const obj: AB = { a: "Hello", b: 42 };

4. Types personnalisés avec type et interface

Bien que les deux soient utilisables pour définir des types, il est généralement recommandé d'utiliser interface pour les définitions complexes de structures de données et de type pour les alias de types simples.

// Interface
interface Point {
    x: number;
    y: number;
}

// Type
type Point = {
    x: number;
    y: number;
};

5. Types littéraux

Les types littéraux permettent de définir des types qui sont exactement les mêmes que les valeurs littérales.

type Direction = "up" | "down" | "left" | "right";

function move(direction: Direction) {
    switch (direction) {
        case "up":
            console.log("Moving up");
            break;
        // autres cas...
    }
}

Mise en pratique : projet fil rouge

Étape 1 : Création du projet

mkdir advanced-types-project
cd advanced-types-project
npm init -y
npm install typescript ts-node --save-dev
npx tsc --init

Structure de base du projet :

advanced-types-project/
├── src/
│   ├── index.ts
│   └── utils/
│       └── logger.ts
├── package.json
└── tsconfig.json

Étape 2 : Création des fichiers

src/utils/logger.ts

export interface LoggerOptions {
    level: "info" | "warn" | "error";
}

export class Logger {
    private options: LoggerOptions;

    constructor(options: LoggerOptions) {
        this.options = options;
    }

    log(message: string, level: LoggerOptions["level"]): void {
        if (this.shouldLog(level)) {
            console.log(`[${level.toUpperCase()}] ${message}`);
        }
    }

    private shouldLog(level: LoggerOptions["level"]): boolean {
        return this.options.level === "info" || this.options.level === level;
    }
}

src/index.ts

import { Logger, LoggerOptions } from "./utils/logger";

const logger = new Logger({ level: "info" });

logger.log("This is an info message", "info");
logger.log("This is a warning message", "warn");
logger.log("This is an error message", "error");

Étape 3 : Configuration de TypeScript

{
    "compilerOptions": {
        "target": "ES6",
        "module": "commonjs",
        "outDir": "./dist",
        "strict": true,
        "esModuleInterop": true,
        "skipLibCheck": true,
        "forceConsistentCasingInFileNames": true
    },
    "include": ["src"]
}

Étape 4 : Compilation et exécution

npx tsc
node dist/index.js

Erreurs frequentes et debugging

1. Type d'argument incorrect

Code incorrect :

function add(a: number, b: string): number {
    return a + b; // Erreur ici
}

const result = add(5, "10");

Code correct :

function add(a: number, b: number): number {
    return a + b;
}

const result = add(5, 10);

2. Propriété non définie sur un objet

Code incorrect :

interface Person {
    name: string;
}

function greet(person: Person) {
    console.log(`Hello, ${person.age}!`);
}

const john = { name: "John" };
greet(john); // Erreur ici

Code correct :

interface Person {
    name: string;
    age?: number; // Optionnel
}

function greet(person: Person) {
    console.log(`Hello, ${person.age ? person.age : 18}!`);
}

const john = { name: "John" };
greet(john);

3. Accès à une propriété inexistante sur un type

Code incorrect :

interface User {
    id: number;
}

function getUserInfo(user: User) {
    return user.email; // Erreur ici
}

Code correct :

interface User {
    id: number;
    email?: string; // Optionnel
}

function getUserInfo(user: User): string | undefined {
    return user.email;
}

Pour aller plus loin

1. Types de tuples

Les types de tuples permettent d'exprimer un tableau avec des éléments de différents types fixés.

type Point = [number, number];

const point: Point = [10, 20];

2. Types génériques avec contraintes

Les types génériques peuvent avoir des contraintes pour s'assurer que les types utilisés respectent certaines conditions.

function logLength<T extends { length: number }>(arg: T): void {
    console.log(`Length is ${arg.length}`);
}

logLength([1, 2, 3]);
logLength("Hello");

3. Types de fonction avec des types de retour

Les fonctions peuvent avoir des types de retour spécifiques.

function add(a: number, b: number): number {
    return a + b;
}

const result = add(5, 10);

Défi pratique : Créer un type générique pour une fonction qui prend un tableau et renvoie le dernier élément

function getLastItem<T>(array: T[]): T | undefined {
    if (array.length === 0) {
        return undefined;
    }
    return array[array.length - 1];
}

const numbers = [1, 2, 3, 4, 5];
const lastNumber = getLastItem(numbers);
console.log(lastNumber); // Output: 5

Ce défi vous permettra de mettre en pratique les concepts de génériques et d'intersections que nous avons vus dans ce tutoriel.

Besoin d'aide sur TypeScript ?

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

Recevoir des conseils

Questions frequentes

Qu'est-ce que les types avancés en TypeScript?
Les types avancés en TypeScript comprennent des concepts tels que les unions, les intersections, les types génériques, et l'utilisation de l'héritage pour créer des structures de données complexes.
Comment utiliser les unions de types en TypeScript?
Les unions de types permettent d'assigner à une variable plusieurs types possibles. Par exemple : `let valeur: string | number = 'bonjour';`
Qu'est-ce que les interfaces en TypeScript et comment les utiliser?
Les interfaces définissent des contrats pour les objets, spécifiant les propriétés et méthodes qu'ils doivent avoir. Elles peuvent être utilisées pour créer des types personnalisés qui servent de modèle à d'autres types.

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.