Convertisseur JSON vers TypeScript Interface en ligne

🏷️ Outils en ligne 📅 15/04/2026 23:50:00 👤 Mezgani said
Json To Typescript Interface Typescript Convertisseur Json Typescript Angular Typage Api

Convertisseur JSON ⇄ TypeScript Interface

Exemples :
Type de déclaration
Export & modificateurs
Propriétés
Interfaces imbriquées
{ } Entrée JSON JSON
TS Interface générée TypeScript

Convertissez votre JSON en interfaces TypeScript en un clic. Détection automatique des types, interfaces imbriquées, options readonly/optional/export. Idéal pour typer vos réponses API Angular.

Pourquoi typer ses réponses API en Angular

Lorsque vous consommez une API REST dans Angular, la réponse JSON est dynamique par nature. Sans typage explicite, TypeScript traite ces données comme any, ce qui annule tous les bénéfices du typage statique : pas d'autocomplete, pas de vérification à la compilation, risques d'erreurs runtime.

Définir une interface TypeScript pour chaque réponse API vous apporte :

  • Autocomplétion dans votre IDE (VS Code, WebStorm)
  • Détection d'erreurs à la compilation, pas au runtime
  • Refactoring sûr — renommer un champ propage l'erreur partout
  • Documentation vivante — l'interface décrit le contrat de l'API
  • Tests plus fiables — les mocks respectent le type attendu
💡 Règle d'or : Une réponse API non typée dans Angular, c'est du JavaScript déguisé en TypeScript. Utilisez cet outil pour convertir vos JSON en interfaces en quelques secondes.
// ❌ Sans typage — dangereux : TypeScript ne peut pas valider
this.http.get('/api/users').subscribe(data => {
  // data est de type 'any' — aucune vérification possible
  console.log(data.name);      // Peut étre undefined à runtime
  console.log(data.emaill);    // Faute de frappe non détectée !
});

// ✅ Avec interface — sûr et autodocumenté
interface User {
  id: number;
  name: string;
  email: string;
  isActive: boolean;
}

this.http.get<User[]>('/api/users').subscribe(users => {
  users.forEach(u => console.log(u.name)); // Typé et validé par le compilateur
  // u.emaill provoque une erreur TS2339 à la compilation
});

Algorithme JSON → TypeScript expliqué

La conversion JSON vers TypeScript repose sur une analyse récursive de chaque valeur. Voici comment l'outil infère les types :

Valeur JSON Exemple Type TypeScript généré
number42, 3.14number
string"Alice"string
booleantrue, falseboolean
nullnullnull
Tableau homogène["a", "b"]string[]
Tableau mixte[1, "a"](number | string)[]
Tableau vide[]unknown[]
Objet imbriqué{"city": "Paris"}Interface dédiée
Note : L'option Interfaces imbriquées génère automatiquement une interface séparée pour chaque objet enfant. Le nom est dérivé en PascalCase depuis la clé JSON parent (ex: addressAddress).
// Exemple complet de conversion JSON → TypeScript

// Entrée JSON
// {
//   "id": 1,
//   "name": "Alice",
//   "tags": ["admin", "user"],
//   "address": { "city": "Paris", "zipCode": "75001" },
//   "metadata": null
// }

// Sortie générée par l'outil

// Interface imbriquée générée en premier
export interface Address {
  city: string;       // inféré depuis "Paris" (string)
  zipCode: string;    // inféré depuis "75001" (string)
}

// Interface racine avec référence à Address
export interface Root {
  id: number;         // inféré depuis 1 (number)
  name: string;       // inféré depuis "Alice" (string)
  tags: string[];     // inféré depuis ["admin","user"] (string[])
  address: Address;   // sous-objet → interface dédiée
  metadata: null;     // null conservé (option nullable activée)
}

Utilisation avec Angular HttpClient

Une fois votre interface générée, intégrez-la directement dans votre service Angular. Le générique <T> de HttpClient accepte votre interface pour typer automatiquement la réponse.

// user.interface.ts — Interface générée par l'outil
export interface Address {
  street: string;
  city: string;
  zipCode: string;
}

export interface User {
  id: number;
  name: string;
  email: string;
  isActive: boolean;
  tags: string[];
  address: Address;
}

// Réponse paginée générique réutilisable
export interface ApiResponse<T> {
  status: number;
  message: string;
  data: T[];
  pagination: Pagination;
}

export interface Pagination {
  page: number;
  perPage: number;
  total: number;
}
// user.service.ts — Service Angular avec typage complet
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { User, ApiResponse } from './user.interface';

@Injectable({ providedIn: 'root' })
export class UserService {
  // URL de base de l'API
  private readonly apiUrl = '/api/v1';

  constructor(private http: HttpClient) {}

  // Récupère la liste paginée des utilisateurs
  getUsers(page = 1): Observable<ApiResponse<User>> {
    return this.http.get<ApiResponse<User>>(
      `${this.apiUrl}/users?page=${page}`
    );
  }

  // Récupère un utilisateur par son identifiant
  getUserById(id: number): Observable<User> {
    return this.http.get<User>(`${this.apiUrl}/users/${id}`);
  }
}
// users.component.ts — Consommation typée dans le composant
import { Component, OnInit } from '@angular/core';
import { UserService } from './user.service';
import { User } from './user.interface';

@Component({
  selector: 'app-users',
  template: `
    <ul>
      <!-- TypeScript garantit que user.name existe et est un string -->
      <li *ngFor="let user of users">
        {{ user.name }} — {{ user.email }}
      </li>
    </ul>
  `
})
export class UsersComponent implements OnInit {
  // Tableau typé : TypeScript connaît la structure exacte
  users: User[] = [];

  constructor(private userService: UserService) {}

  ngOnInit(): void {
    this.userService.getUsers().subscribe(response => {
      // response.data est de type User[] — autocomplétion complète
      this.users = response.data;
    });
  }
}
💡 Astuce Angular : Créez un fichier *.interface.ts dédié par entité métier (ex: user.interface.ts, product.interface.ts) et exportez toutes vos interfaces depuis un fichier index.ts centralisé.

Interfaces imbriquées avancées

Les APIs réelles retournent souvent des structures complexes avec plusieurs niveaux d'imbrication. L'outil gère automatiquement ces cas en créant une interface par niveau d'objet.

// JSON complexe avec 3 niveaux d'imbrication
// {
//   "order": {
//     "id": "ORD-001",
//     "customer": {
//       "id": 42,
//       "billing": { "country": "FR", "vat": "FR12345" }
//     },
//     "items": [{ "sku": "ANG-01", "qty": 2 }]
//   }
// }

// Interfaces générées (des plus profondes aux plus hautes)

export interface Billing {
  country: string;   // 3e niveau
  vat: string;
}

export interface Customer {
  id: number;        // 2e niveau
  billing: Billing;  // référence vers l'interface Billing
}

export interface Items {
  sku: string;       // interface pour les éléments du tableau
  qty: number;
}

export interface Order {
  id: string;           // 1er niveau
  customer: Customer;   // référence vers Customer
  items: Items[];       // tableau d'interfaces Items
}

export interface Root {
  order: Order;         // interface racine
}
Note : Si vous désactivez l'option Interfaces imbriquées, les objets sont typés comme Record<string, unknown> — utile quand vous ne voulez pas multiplier les déclarations pour des objets simples.

Zod & class-validator pour la validation runtime

Les interfaces TypeScript ne valident qu'à la compilation. Au runtime, si l'API change son format (déploiement serveur, vérsion API), TypeScript ne peut pas le détecter. Des bibliothèques de validation runtime complètent parfaitement les interfaces.

Zod est la solution la plus populaire en 2024 pour ce cas d'usage.

// Avec Zod : validation runtime + inférence TypeScript automatique
// npm install zod

import { z } from 'zod';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';

// Schéma Zod — définit la forme et valide à l'exécution
const UserSchema = z.object({
  id:       z.number(),         // doit être un number
  name:     z.string(),         // doit être une string
  email:    z.string().email(), // doit être un email valide
  isActive: z.boolean(),        // doit être un boolean
  tags:     z.array(z.string()),
  metadata: z.nullable(z.string()), // string ou null
});

// TypeScript infère automatiquement le type depuis le schéma
type User = z.infer<typeof UserSchema>;
// Équivalent à :
// interface User { id: number; name: string; email: string; ... }

// Utilisation dans un service Angular
getUser(id: number) {
  return this.http.get(`/api/users/${id}`).pipe(
    // Valide la réponse API au runtime — lève une erreur si le format change
    map(data => UserSchema.parse(data))
  );
}
// Avec class-validator (NestJS / Angular côté formulaire)
// npm install class-validator class-transformer

import { IsNumber, IsString, IsEmail, IsBoolean, IsArray } from 'class-validator';
import { plainToInstance, Transform } from 'class-transformer';

// Classe DTO avec décorateurs de validation
export class UserDto {
  @IsNumber()
  id!: number;

  @IsString()
  name!: string;

  @IsEmail()
  email!: string;

  @IsBoolean()
  isActive!: boolean;

  @IsArray()
  @IsString({ each: true })
  tags!: string[];
}

// Transformer la réponse API brute en instance typée et validée
import { validate } from 'class-validator';

async function parseUser(rawData: unknown): Promise<UserDto> {
  const user = plainToInstance(UserDto, rawData);
  const errors = await validate(user);
  if (errors.length > 0) {
    throw new Error('Données API invalides : ' + JSON.stringify(errors));
  }
  return user;
}
🚀 Conseil : Utilisez Zod pour les projets Angular modernes (léger, tree-shakeable, compatible signals). Utilisez class-validator si vous partagez des DTO avec un backend NestJS.

Bonnes pratiques de typage TypeScript

Voici les règles essentielles pour un typage TypeScript robuste dans vos projets Angular :

  • Un fichier par entitéuser.interface.ts, product.interface.ts. Ne regroupez pas tout dans un seul fichier.
  • Préfixez vos interfaces — Certains projets utilisent IUser mais la convention Angular recommande User sans préfixe.
  • Utilisez readonly pour les données immuables — Les réponses API ne doivent pas être modifiées directement.
  • Typage des tableaux — Préférez User[] à Array<User> (plus lisible).
  • Évitez any — Utilisez unknown si le type est vraiment inconnu, puis affinez avec un type guard.
  • Documentez avec des commentaires JSDoc — Les commentaires apparaissent dans l'autocomplete VS Code.
// ❌ Anti-pattern — à éviter absolument
interface User {
  [key: string]: any; // Annule tout le bénéfice du typage
}

// ✅ Bonne pratique — typage strict avec JSDoc
export interface User {
  /** Identifiant unique de l'utilisateur (auto-incrémenté) */
  readonly id: number;
  /** Nom complet affiché dans l'interface */
  name: string;
  /** Adresse email — doit être unique en base */
  email: string;
  /** Rôle de l'utilisateur dans l'application */
  role: 'admin' | 'editor' | 'viewer'; // Union type littérale
  /** Date de création au format ISO 8601 */
  createdAt: string;
  /** Adresse postale — optionnelle */
  address?: Address;
}

// Type guard pour valider une donnée inconnue
function isUser(data: unknown): data is User {
  return (
    typeof data === 'object' &&
    data !== null &&
    typeof (data as User).id === 'number' &&
    typeof (data as User).name === 'string'
  );
}

// Utilisation du type guard
const rawData: unknown = await fetchUser();
if (isUser(rawData)) {
  // TypeScript connaît maintenant le type User avec certitude
  console.log(rawData.name); // Autocomplétion disponible
}
Nouveauté Angular 17+ : Avec les Angular Signals, typez vos signaux dès leur création : users = signal<User[]>([]);. Le typage se propage automatiquement dans tous les templates qui utilisent le signal.

Conclusion

Le typage des réponses API est l'une des pratiques les plus impactantes que vous puissiez adopter dans un projet Angular. En quelques secondes, cet outil transforme n'importe quel JSON en interfaces TypeScript propres, avec support des types imbriqués, des tableaux, des nullables et des modificateurs readonly / optional.

Complétez vos interfaces avec Zod pour la validation runtime, et structurez vos fichiers par entité métier pour un code maintenable sur le long terme. Un projet bien typé est un projet où les bugs se détectent à la compilation, pas en production.

✅ À retenir : Collez votre JSON dans l'outil, copiez l'interface générée dans un fichier *.interface.ts, et utilisez-la comme générique dans vos appels HttpClient.get<VotreInterface>(). Votre IDE fait le reste.