ts-pattern pour TypeScript : guide complet avec exemples
La bibliothèque ts-pattern apporte à TypeScript un mécanisme puissant et expressif de filtrage par motif (pattern matching), inspiré de langages comme OCaml, Rust, Haskell et Scala. Au lieu de longues chaînes if-else ou switch-case, ts-pattern permet de décrire la logique conditionnelle de manière déclarative, en vérifiant la structure et les types de données. C'est particulièrement utile pour travailler avec des types de données algébriques (ADT), comme les unions discriminées, les valeurs optionnelles (Option) ou les résultats (Result).
Pourquoi l'utiliser ? Premièrement, le code devient plus lisible et concis. Au lieu d'analyser des objets imbriqués complexes avec de multiples vérifications, vous décrivez la structure de données souhaitée, et la bibliothèque trouve automatiquement la correspondance. Deuxièmement, ts-pattern assure une vérification d'exhaustivité (exhaustiveness check) : si vous n'avez pas traité tous les cas possibles, TypeScript génère une erreur à la compilation. Cela réduit considérablement le nombre de bugs liés aux états oubliés. Troisièmement, la bibliothèque est entièrement typée et s'intègre au système de types de TypeScript, rendant le refactoring sûr et prévisible.
ts-pattern n'est pas qu'un simple remplacement de switch. C'est un outil complet de décomposition des données qui permet de filtrer non seulement les valeurs, mais aussi leurs types, structures, plages et même des prédicats personnalisés. La bibliothèque est activement utilisée dans des projets où la fiabilité et l'expressivité sont essentielles : des applications frontend avec React/Redux aux services backend avec Node.js.
Installation
L'installation de la bibliothèque se fait via un gestionnaire de paquets npm (ou yarn/pnpm). Assurez-vous que votre projet utilise TypeScript version 4.0 ou supérieure.
npm install ts-pattern
Une fois installée, la bibliothèque est prête à l'emploi. Aucune configuration supplémentaire de tsconfig.json n'est nécessaire.
Démarrage rapide
Commençons par un exemple classique : le traitement du résultat d'une requête HTTP. Imaginons une union discriminée décrivant l'état de chargement des données.
import { match } from 'ts-pattern';
// Définition des états possibles
type State =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success'; data: string }
| { status: 'error'; error: Error };
// Fonction qui retourne un texte selon l'état
function getStatusMessage(state: State): string {
return match(state)
.with({ status: 'idle' }, () => 'En attente...')
.with({ status: 'loading' }, () => 'Chargement...')
.with({ status: 'success' }, ({ data }) => `Données : ${data}`)
.with({ status: 'error' }, ({ error }) => `Erreur : ${error.message}`)
.exhaustive(); // vérifie que tous les cas sont traités
}
// Exemples d'utilisation
console.log(getStatusMessage({ status: 'idle' })); // "En attente..."
console.log(getStatusMessage({ status: 'loading' })); // "Chargement..."
console.log(getStatusMessage({ status: 'success', data: 'Bonjour le monde !' })); // "Données : Bonjour le monde !"
console.log(getStatusMessage({ status: 'error', error: new Error('404') })); // "Erreur : 404"
Cet exemple illustre l'idée principale : nous faisons correspondre l'objet state à différents motifs. Chaque motif est une description partielle de la structure de l'objet. Si la structure correspond, la fonction associée est exécutée. La méthode .exhaustive() garantit qu'aucun cas n'a été oublié.
Méthodes et fonctions principales
La bibliothèque propose plusieurs fonctions et méthodes clés. Examinons-les en détail.
1. match(value)
Signature : match<I, O>(value: I): Match<I, O>
Fonctionnement :
Aussi dans la bibliothèque
Génération de PDF en C++ : aperçu des bibliothèques et outils
Rate Limiting en Java : bibliothèques, algorithmes et implémentation
Client HTTP pour PHP : Guzzle
Envoi de SMS en Java : Aperçu et exemples d'utilisation des bibliothèques API (Twilio, Nexmo)