Skip to content

protobuf-ts-types 允许你用 proto 格式定义语言无关的 message 类型,然后无需额外代码生成,即可从中推断出 TypeScript 类型。

Try on github.dev | View on CodeSandbox

警告: 这只是一个概念验证,尚未准备好用于生产环境。更多细节请参考下面的 Limitations 部分。

Screenshot

用法

首先,安装这个包。

npm install https://github.com/nathanhleung/protobuf-ts-types

然后,在 TypeScript 中使用它。

import { pbt } from "protobuf-ts-types";

const proto = `
  syntax = "proto3";
  message Person {
   string name = 1;
   int32 id = 2;
   bool is_ceo = 3;
   optional string description = 4;
  }
  message Group {
    string name = 1;
    repeated Person people = 2;
  }
`;

// `Proto` 是 message 名称到 message 类型的映射,从上面的 `proto` 源代码字符串推断而来。
type Proto = pbt.infer<typeof proto>;
type Person = Proto["Person"];
type Person2 = pbt.infer<typeof proto, "Person">;

// `Person` 和 `Person2` 是相同的类型:
// ```
// {
//   name: string;
//   id: number;
//   is_ceo: boolean;
//   description?: string;
// }
// ```

type Group = pbt.infer<typeof proto, "Group">;

function greetPerson(person: Person) {
 console.log(`Hello, ${person.name}!`);
 if (person.description) {
  console.log(`${person.description}`);
 } else {
  console.log("(no description)");
 }
}

function greetGroup(group: Group) {
 console.log(`=========${"=".repeat(group.name.length)}===`);
 console.log(`= Hello, ${group.name}! =`);
 console.log(`=========${"=".repeat(group.name.length)}===`);
 for (const person of group.people) {
  greetPerson(person);
  console.log();
 }
}

// 如果 `Group` 或任何单个 `Person` 的结构与类型不匹配,TypeScript 将显示错误。
greetGroup({
 name: "Hooli",
 people: [
  {
   name: "Gavin Belson",
   id: 0,
   is_ceo: true,
   description: "CEO of Hooli",
  },
  {
   name: "Richard Hendricks",
   id: 1,
   is_ceo: true,
   description: "CEO of Pied Piper",
  },
  {
   name: "Dinesh Chugtai",
   id: 2,
   is_ceo: false,
   description: "Software Engineer",
  },
  {
   name: "Jared Dunn",
   id: 3,
   is_ceo: false,
  },
 ],
});

// 输出:
// ```
// =================
// = Hello, Hooli! =
// =================
// Hello, Gavin Belson!
// CEO of Hooli
//
// Hello, Richard Hendricks!
// CEO of Pied Piper
//
// Hello, Dinesh Chugtai!
// Software Engineer
//
// Hello, Jared Dunn!
// (no description)
// ```

Limitations

API

pbt

顶层导出的命名空间。

import { pbt } from "protobuf-ts-types";

pbt.infer<Proto extends string, MessageName extends string = "">

给定一个 proto 源代码字符串,推断源代码中 message 的类型。

返回值