Convertisseur Protobuf vers TypeScript
Collez un schéma .proto. Obtenez des interfaces TypeScript avec les bons types, y compris les entiers 64 bits en chaînes selon la spec de mapping JSON proto3.
Entrée (schéma .proto)
Sortie (TypeScript)
Ce que fait cet outil
Vous avez un schéma Protocol Buffers et un frontend TypeScript qui doit parler à un backend gRPC ou transcodé HTTP servant ces messages. La chaîne officielle de codegen (protoc avec ts-proto ou protobuf-ts) demande d'installer des outils, configurer des plugins et brancher une étape de build. Ce convertisseur fait le même boulot dans votre navigateur — collez, copiez la sortie, déposez-la dans votre projet.
Le mapping de types suit ce à quoi ressemblent les types écrits à la main dans de vraies bases de code : string/bytes → string/Uint8Array, bool → boolean, les types numériques plus petits (int32, uint32, float, double) → number, et les entiers 64 bits (int64, uint64, fixed64, sfixed64, sint64) → string pour correspondre à la spec de mapping JSON proto3. repeated T devient T[], map<K, V> devient Record<K, V>, les messages imbriqués deviennent des déclarations interface imbriquées.
Les noms de champs sont convertis de snake_case (convention Protobuf) en camelCase (convention JavaScript/TypeScript) — correspondant au comportement par défaut de l'encodeur JSON proto3. Les enums deviennent des types union de littéraux de chaîne (type OrderStatus = 'ORDER_STATUS_UNSPECIFIED' | 'ORDER_STATUS_PENDING' | ...), ce que la plupart des bases de code TypeScript préfèrent — pas besoin du coût runtime d'un enum. Le convertisseur tourne entièrement dans votre navigateur ; rien de votre schéma ne quitte la page.
Comment l'utiliser
Trois étapes. La sortie est prête à coller dans un fichier <code>.ts</code> en quelques secondes.
Collez votre schéma .proto
Déposez le schéma dans l'éditeur de gauche. syntax = "proto3"; en haut est OK mais optionnel. Le parser gère les blocs message imbriqués, les déclarations enum, oneof, map<K, V> et les options de champ. Les imports sont reconnus mais ignorés — collez les types importés en ligne si vous en avez besoin.
La conversion des noms de champs est automatique : order_id dans .proto devient orderId en TypeScript. Les noms de message et d'enum restent tels quels (déjà en PascalCase).
Lisez la sortie
À droite : du TypeScript avec export interface pour chaque message et export type avec une union de littéraux de chaîne pour chaque enum. Les types imbriqués viennent avant leur parent, donc le fichier est en ordre de déclaration. Ajoutez le fichier à votre projet et importez les interfaces depuis votre client gRPC ou handler fetch.
Utilisez les types
Branchez les interfaces sur votre client fetch / gRPC-Web / Connect-RPC. La forme correspond à l'encodage JSON proto3, donc les réponses JSON se parsent directement dans la forme typée sans conversion manuelle. Ajustez la gestion des int64 si votre serveur utilise un encodage JSON non standard.
Quand ça fait vraiment gagner du temps
Esquisser des types pour un nouveau frontend gRPC
Vous construisez une nouvelle app TS au-dessus d'un service gRPC existant. Pas besoin de codegen complet pour l'instant — juste les formes d'interfaces pour typer vos appels fetch. Collez le .proto, déposez la sortie dans types.ts, vous êtes typé.
Relire un changement d'API Protobuf
Un coéquipier backend a ajouté des champs à un message. Vous voulez voir comment ça affecte les types du frontend sans lancer le build. Collez le nouveau .proto, comparez la sortie TypeScript avec vos types actuels, laissez un commentaire de revue ciblé.
Recouper les types générés
Votre build utilise protobuf-ts ou ts-proto, qui produisent des types avec leurs propres conventions. Collez le schéma ici pour avoir une référence propre de ce à quoi ressemblent des interfaces TS simples, utile pour la doc ou la planification d'une migration.
Scripts jetables et intégrations ponctuelles
Vous écrivez un script Node rapide qui POST du JSON vers une gRPC-gateway. Monter toute la chaîne Protobuf pour 30 lignes, c'est exagéré. Récupérez les interfaces ici et vous avez la sécurité de types sans cérémonie.
Questions courantes
Est-ce que mon schéma est envoyé quelque part ?
Non. Le parser et l'émetteur TS tournent entièrement dans votre navigateur en JavaScript. Ouvrez les DevTools et regardez l'onglet Network pendant que vous collez — zéro requête. Pratique quand votre schéma contient des noms de types internes, des chemins de package ou tout ce que vous ne voudriez pas envoyer à un service tiers.
Pourquoi les champs int64 sont typés en string ?
Les Number JavaScript sont des doubles IEEE-754, qui perdent en précision au-dessus de 2^53. Le mapping JSON proto3 officiel exige que int64, uint64, fixed64, sfixed64 et sint64 soient encodés en chaînes JSON. Donc l'interface TS utilise string pour ceux-là — ça correspond à ce que votre serveur envoie réellement. Si vous voulez du bigint à la place, faites un find-replace dans la sortie.
Pourquoi les enums sont des unions de chaînes au lieu d'enums TS ?
La plupart des projets TypeScript préfèrent aujourd'hui les unions de littéraux de chaîne aux enums TS — pas de coût runtime, meilleur tree-shaking, et ça correspond à l'encodage JSON proto3 (qui sérialise les enums sous leur nom de chaîne). Si vous voulez un const enum ou un enum numérique, la conversion depuis l'union est mécanique.
Comment gère-t-il map<K, V> ?
Rendu en Record<K, V>. Les maps Protobuf avec des clés non-string (par ex. map<int32, string>) deviennent Record<number, string>. JSON n'a que des clés string, donc à l'exécution les clés seront des chaînes même si le proto dit int — c'est une bizarrerie de la spec JSON proto3, pas du convertisseur.
Les champs sont-ils marqués optionnels ?
Non. Les champs proto3 sont toujours présents en sortie JSON (avec des valeurs par défaut — chaîne vide, 0, false, [], {}), donc l'interface TypeScript marque chaque champ comme requis. Si vous voulez vraiment des champs optionnels (parce que votre runtime peut les omettre), ajoutez ? manuellement après chaque nom de champ.
Gère-t-il oneof ?
Chaque champ d'un oneof est émis comme un champ d'interface normal. La sortie n'impose pas la contrainte « exactement un » qu'implique oneof — pour ça il faudrait une union discriminée, qui dépend de la sémantique de votre runtime. Éditez la sortie à la main si vous voulez des types plus stricts.
Outils associés
Si vous travaillez avec Protobuf, JSON et TypeScript, ces outils se complètent :