将protobuf转换成typescript类型文件(支持注释,支持import依赖)
npm install pb-to-ts
import Pbts from 'pb-to-ts';
const pbts = new Pbts({
input: './proto/xxx',
output: './src/types/xxx/',
})
pbts.compile()
import Pbts from 'pb-to-ts';
const pbts1 = new Pbts({
input: './proto/xxx',
output: './src/types/xxx/',
})
const pbts2 = new Pbts({
input: './proto/xxx',
output: './src/types/xxx/',
})
pbts1.compile()
pbts2.compile()
利用 protobuf.js 将 protobuf 文件转化为抽象语法树(AST),下面是 protobuf.js 解析出来的数据类型,因为目标主要是面向前端使用的 Typescript 文件,所以我们主要需要针对 Field,Enum,Method 这三种数据类型进行 Typescript 转换。
Type (T) | Extends | Type-specific properties |
---|---|---|
ReflectionObject | options | |
Namespace | ReflectionObject | nested |
Root | Namespace | nested |
Type | Namespace | fields |
Enum | ReflectionObject | values |
Field | ReflectionObject | rule, type, id |
MapField | Field | keyType |
OneOf | ReflectionObject | oneof (array of field names) |
Service | Namespace | methods |
Method | ReflectionObject | type, requestType, responseType, requestStream, responseStream |
Field 主要指的就是 protobuf 中的 message ,它可以转换为 TS 里面的 interface。其中 PB 类型和 TS 类型存在一个转换关系。这里存在一个问题即是 int64 超出 js 的 number 类型,如果强制转换则会丢失精度,默认我们将它转换为 string。
repeated关键字则是数组的一个表现。
Field type | Expected JS type (create, encode) |
---|---|
s-/u-/int32 s-/fixed32 | number |
s-/u-/int64 s-/fixed64 | number或者string |
float double | number |
bool | boolean |
string | string |
bytes | string |
枚举是 Protobuf 类型也是 Typescript 类型,只需做简单转换即可,但是 Protobuf 中的 Enum 有可能存在于 message 当中,而此时,它并非接口参数实现,需要注意。
rpc服务里面的一个方法即是一个method,一般里面包含两个message,分别是入参和出参。
service Archive {
rpc SaveStudentInfo(SaveStudentInfoReq) returns (CommonRsp); // 保存学生基本信息
}
转成
export type SaveStudentInfo = (params: SaveStudentInfoReq) => Promise<CommonRsp>;