Introduction : JSON et TypeScript — le duo idéal pour travailler avec les données
\nJSON (JavaScript Object Notation) est un format léger d'échange de données qui est devenu le standard de facto pour les interactions entre client et serveur, ainsi que pour le stockage de configurations et la transmission d'informations structurées. TypeScript, en tant que sur-ensemble strictement typé de JavaScript, fournit des outils puissants pour un travail sûr et prévisible avec JSON. Dans cet article, nous allons voir en pratique comment analyser (convertir une chaîne JSON en objet) et sérialiser (convertir un objet en chaîne JSON) correctement les données en TypeScript, en évitant les erreurs typiques et en utilisant les capacités du système de types.
\n\nLes bases : JSON.parse() et JSON.stringify() en TypeScript
\nTypeScript hérite entièrement des méthodes intégrées de JavaScript pour travailler avec JSON : JSON.parse() et JSON.stringify(). Cependant, leur utilisation dans un environnement strictement typé nécessite une approche particulière.
JSON.parse() — de la chaîne à l'objet
\nLa méthode JSON.parse() prend une chaîne JSON et retourne un objet. En TypeScript, le résultat a par défaut le type any, ce qui nous prive de tous les avantages du typage. Prenons un exemple :
const jsonString = '{"name": "TypeScript", "version": 5.3}';\nconst parsed: any = JSON.parse(jsonString);\nconsole.log(parsed.name); // Fonctionne, mais pas d'autocomplétion ni de vérification de types\nPour obtenir un résultat typé, utilisez une assertion de type (type assertion) :
\ninterface Language {\n name: string;\n version: number;\n}\n\nconst jsonString = '{"name": "TypeScript", "version": 5.3}';\nconst parsed = JSON.parse(jsonString) as Language;\nconsole.log(parsed.name.toUpperCase()); // L'autocomplétion fonctionne !\n\nJSON.stringify() — de l'objet à la chaîne
\nJSON.stringify() sérialise un objet en une chaîne JSON. TypeScript vérifie que l'objet passé est valide pour la sérialisation (ne contient pas de fonctions, undefined, Symbol, etc.).
interface User {\n id: number;\n name: string;\n isActive: boolean;\n}\n\nconst user: User = { id: 1, name: "Alice", isActive: true };\nconst jsonString = JSON.stringify(user);\nconsole.log(jsonString); // '{"id":1,"name":"Alice","isActive":true}'\n\nTechniques avancées : typage et gestion des erreurs
\nEn pratique, le travail avec JSON est rarement parfait. Les données peuvent arriver du serveur dans un format inattendu, contenir des champs supplémentaires ou manquer de champs obligatoires. Voyons comment TypeScript aide à gérer ces problèmes.
\n\nCréation d'une fonction générique pour un parsing sécurisé
\nÉcrivons une fonction universelle qui prend une chaîne JSON et retourne un résultat typé avec gestion des erreurs :
\nfunction safeParse<T>(json: string): T | null {\n try {\n return JSON.parse(json) as T;\n } catch (error) {\n console.error("Erreur de parsing JSON :", error);\n return null;\n }\n}\n\n// Utilisation\ninterface Product {\n id: number;\n title: string;\n price: number;\n}\n\nconst rawData = '{"id": 101, "title": "Laptop", "price": 999.99}';\nconst product = safeParse<Product>(rawData);\nif (product) {\n console.log(product.title); // "Laptop"\n}\n\nValidation des données avec des gardiens de type personnalisés
\nMême après une assertion de type as T, TypeScript ne vérifie pas que les données correspondent réellement à l'interface. Pour une validation à l'exécution, utilisez des type guards :
function isProduct(obj: any): obj is Product {\n return (\n typeof obj === 'object' &&\n obj !== null &&\n typeof obj.id === 'number' &&\n typeof obj.title === 'string' &&\n typeof obj.price === 'number'\n );\n}\n\nconst rawData = '{"id": "abc", "title": "Phone", "price": 599}';\nconst parsed = JSON.parse(rawData);\nif (isProd