You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将gRPC Proto文件编译为TypeScript并正确标记非可选属性?

问题:Proto编译为TypeScript时属性被标记为可选,如何确保必填属性正确生成?

我用以下脚本将多个proto文件编译为TypeScript:

yarn proto-loader-gen-types \
    --grpcLib=@grpc/grpc-js \
    --outDir=${OUT_DIR} \
    ${IN_DIR}/*.proto

其中定义了一个Bool消息:

message Bool {
  bool state = 1;
}

但编译生成的TypeScript文件中所有对象属性均被标记为可选:

export interface Bool {
  'state'?: (boolean);
}

export interface Bool__Output {
  'state'?: (boolean);
}

编写测试时,预期返回{ state: true }能得到正确结果,但预期{ state: false }时却得到空对象{}。请问如何编译proto文件,确保非可选属性被正确标记为必填?


解决方法

1. 修改编译脚本,添加关键参数

更新编译命令,加入--keepCase(保持字段原生大小写)和--defaults(强制生成包含默认值逻辑的必填类型标记)参数:

yarn proto-loader-gen-types \
    --grpcLib=@grpc/grpc-js \
    --outDir=${OUT_DIR} \
    --keepCase \
    --defaults \
    ${IN_DIR}/*.proto

2. 针对proto2语法:显式标记required

如果你的proto文件基于proto2语法,可以直接给字段加上required关键字,强制标记为必填:

message Bool {
  required bool state = 1;
}

注意:proto3已移除required关键字,需通过编译参数调整类型生成逻辑

3. 解决false值被忽略的问题

protobuf默认会省略值为默认值的字段(bool类型默认值为false),导致返回空对象。可以在加载proto配置时开启keepDefaultValues选项,保留默认值字段:

const packageDefinition = loader.loadSync(
  [path.join(__dirname, '*.proto')],
  {
    keepCase: true,
    defaults: true,
    keepDefaultValues: true, // 保留默认值字段
    longs: String,
    enums: String,
    bytes: Buffer,
  }
);

调整后,生成的TypeScript接口属性会被标记为必填,同时{ state: false }也能正常返回,不会被省略。

内容的提问来源于stack exchange,提问作者dokgu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 20:25:10