如何将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
相关产品推荐
相关产品推荐

