ts-proto
.proto
ファイルを強く慣用型タイプスクリプトファイルに変換します!
TS-PROTOの2.xリリースは、低レベルのプロトブフシリアル化を移行しました。これは、そのencode
およびdecode
メソッドの使用を由緒あるが、老化して停滞したprotobufjs
パッケージを@bufbuild/protobuf
に移行しました。
encode
とdecode
メソッドのみを使用した場合、これは主に非壊れた変更である必要があります。
ただし、古いprotobufjs
Writer
またはReader
クラスを使用したコードを使用した場合、新しい@bufbuild/protobuf
クラスを使用するためにコードを更新する必要があります。
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
@bufbuild/protobuf
に移行することがブロッカーである場合、 ts-proto
バージョンを1.x
に固定できます。
免責事項と謝罪:私はTS-Proto 2.xをアルファリリースとしてリリースするつもりでしたが、セマンティックリリースの構成を正しく取得していなかったため、TS-PROTO 2.Xは適切なアルファなしの主要なリリースとして公開されました/ベータサイクル。
リリースがまだ新鮮である間に出会った問題についてレポート(またはより良いPRS!)を提出できれば、それは大歓迎です。
移行に関する他の人のためのヒントやコツも感謝します!
ts-proto
目次
概要
クイックスタート
buf
ESM
目標
非ゴール
例の例
ハイライト
自動バッチ / n+1予防
使用法
サポートされているオプション
NestJSサポート
ウォッチモード
基本的なGRPC実装
スポンサー
発達
仮定
トト
1つの取り扱い
デフォルト値と未解決のフィールド
よく知られているタイプ
ラッパータイプ
JSONタイプ(構造タイプ)
タイムスタンプ
数字タイプ
オプションの値の現在のステータス
TS-Protoは、Protobufスキーマからタイプスクリプトタイプを生成します。
つまり、 person.proto
schemaのようなものを与えられました:
メッセージ担当者{文字列名= 1; }
TS-PROTOは、次のようなperson.ts
ファイルを生成します。
インターフェイスパーソン{ 名前:string} const person = { エンコード(人):ライター{...} デコード(リーダー):人{...} トジソン(人):不明{...} fromjson(data):person {...}}
また、サービスについても知っており、それらのタイプも生成します。
インターフェイスpingserviceをエクスポート{ ping(リクエスト:pingrequest):約束<pingResponse>;}
また、 PingService
のクライアント実装も生成されます。現在、TWIRP、GRPC-WEB、GRPC-JS、およびNESTJSがサポートされています。
npm install ts-proto
protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto --ts_proto_out=. ./simple.proto
(出力パラメーター名、 ts_proto_out
は、プラグインの名前の接尾辞、すなわち--plugin=./node_modules/.bin/protoc-gen-ts_proto
パラメーターに_out
prefixになります。 Per protoc
のCLIコンベンション。)
Windowsでは、 protoc --plugin=protoc-gen-ts_proto=".node_modules.binprotoc-gen-ts_proto.cmd" --ts_proto_out=. ./simple.proto
を参照)
最新のprotoc
使用していることを確認してください(プラットフォームのインストール手順を参照してください。 protoc
3.0.0
_opt
フラグをサポートしていません
これにより、指定された*.proto
タイプの*.ts
ソースファイルが生成されます。
これらのソースファイルをNPMパッケージにパッケージ化してクライアントに配布する場合は、通常どおりtsc
実行して.js
/ .d.ts
ファイルを生成し、通常のNPMパッケージとして出力を展開します。
BUFを使用している場合は、 buf.gen.yaml
ファイル(docs)にstrategy: all
します。
バージョン:V1Plugins: - 名前:tsout:../gen/tsstrategy:allpath:../node_modules/ts-proto/protoc-gen-ts_proto
buf push
無関係な.proto
ファイルを読むのを防ぐために、 buf.yaml
のように構成します:
ビルド:除外:[node_modules]
また、BUFレジストリに公開されている公式プラグインを使用することもできます。
バージョン:V1Plugins: - プラグイン:buf.build/community/stephenh-ts-protoout:../gen/tsopt: -OUTPUTSERVICES = ... -UESEXACTTYPES = ...
esModuleInterop
を使用して最新のTSセットアップを使用している場合、またはESM環境で実行している場合は、次のts_proto_opt
を渡す必要があります。
esModuleInterop=true
tsconfig.json
でesModuleInterop
を使用している場合、and
importSuffix=.js
ESM環境で生成されたTS-PROTOコードを実行する場合
ts-proto
生成するコードに関しては、一般的な目標は次のとおりです。
慣用型タイプスクリプト/ES6タイプ
ts-proto
、組み込みのGoogle/Java-Esque JS protoc
コードまたは「 .d.ts
ファイルを作成します*.js
コメント」というprotobufjs
のいずれかからのクリーンな休憩です。
(技術的には、 protobufjs/minimal
Packageが実際にバイトを読み取り/書き込むために使用されます。)
TypeScript-First出力
クラス上のインターフェイス
可能な限り、タイプは単なるインターフェイスであるため、通常のハッシュ/データ構造のようにメッセージを使用できます。
codegen *.proto
.proto
*.ts
ワークフローのみをサポートしています。
TS-Protoは、すぐに使用できるRPCフレームワークではないことに注意してください。代わりに、それはより多くの構成オプションで目撃されているスイスのナイフのようなものであり、その上にあなたが望むRPCフレームワークを正確に構築できます(つまり、あなたの会社のProtoBufエコシステムと統合するのが最適です。良くも悪くも、Protobuf RPCは依然としてやや断片化された生態系です)。
TS-Protoの上に構築されたすぐに使用できるRPCフレームワークが必要な場合は、いくつかの例があります。
nice-grpc
starpc
(潜在的な貢献者については、他のフレームワーク/ミニフレームワーク、さらにはブログ投稿/チュートリアルを開発した場合、 ts-proto
の使用については、喜んでリンクさせてください。)
また、 google.api.http
ベースのGoogleクラウドAPIのクライアントをサポートしていません。PRを送信する場合は#948を参照してください。
生成されたタイプは「データだけ」です。
インターフェイスをエクスポートsimple { 名前:文字列; 年齢:数; createdat:日付|未定義; 子供:子供|未定義; 状態:StateEnum; 孫:子供[]; コイン:number [];}
encode
/ decode
ファクトリーメソッド:
const simple = {{{{ create(baseObject?:deeppartial <simple>):simple {...}、 エンコード(メッセージ:simple、writer:writer = writer.create()):writer {...}、 デコード(読者:読者、長さ?:番号):simple {...}、 fromjson(オブジェクト:任意):simple {...}、 frompartial(object:deeppartial <simple>):simple {...}、 Tojson(メッセージ:シンプル):不明{...}、};
これにより、次のような慣用的なTS/JSの使用が可能になります。
const bytes = simple.encode({name:...、age:...、...})。finish(); const simple = simple.decode(reader.create(bytes)); const {name、age } = simple;
クラスを作成せず、適切なゲッター/セッターを呼び出すことなく、他のレイヤーに出会うときに統合を劇的に容易にすることができます。
「オプションの種類をバックバックしてください」という貧しい男の試み
標準プロトブフラッパータイプ、すなわちgoogle.protobuf.StringValue
は、オプションの値としてマッピングされていますstring | undefined
。つまり、プリミティブにとっては、Protobufタイプのシステムにはオプションのタイプがあるふりをすることができます。
(更新:TS-Protoは、Proto3 optional
キーワードもサポートしています。)
タイムスタンプはDate
としてマッピングされます
( useDate
パラメーターで構成できます。)
fromJSON
/ toJSON
protobufjs
とは異なり、Proto3 Canonical JSONエンコード形式(タイムスタンプはISO文字列です)を使用します。
ObjectIdsは、 mongodb.ObjectId
としてマッピングできます
( useMongoObjectId
パラメーターで構成可能。)
(注:これは現在、TWIRPクライアントによってのみサポートされています。)
TS-Protoのクライアントを使用して、SQLアプリケーションのN+1問題と同様に、マイクロサービスをバックエンドでコールする場合、マイクロサービスクライアントが(個々のリクエストを提供するとき)、複数の個別のRPC呼び出しを誤ってトリガーするのは簡単です。 「Get Book 1」、「Get Book 2」、「Get Book 3」、それは本当に単一の「Get Books [1、2、3]」にバッチされるはずです(バックエンドがバッチ指向のRPCメソッドをサポートすると仮定します)。
TS-Protoはこれを支援し、本質的に個々の「Get Book」コールをバッチ付き「Get Books」コールに自動バッチします。
TS-PROTOがこれを行うには、次のバッチ条約でサービスのRPCメソッドを実装する必要があります。
Batch<OperationName>
Batch<OperationName>
入力タイプには、単一の繰り返しフィールドがあります(つまり、 repeated string ids = 1
)
Batch<OperationName>
出力タイプには次のいずれかがあります。
出力順序が入力ids
注文と同じである単一の繰り返しフィールド(つまり、 repeated Foo foos = 1
出力への入力のマップ(IE map<string, Entity> entities = 1;
)
TS-PROTOがこのパターンのメソッドを認識すると、クライアント、つまりクライアントの<OperationName>
の「非バッチ」バージョン、つまりclient.Get<OperationName>
自動的に作成します。
これにより、クライアントコードは、個々のGet<OperationName>
コール(クライアントのビジネスロジックを実装するときに一般的に望ましい/簡単です)を作成できるという幻想を提供しますが、TS-Protoが提供する実際の実装は、 Batch<OperationName>
を作成することになります。バックエンドサービスへの呼び出し。
また、すべてのgetDataLoaders
メソッドにGo-Style ctx
パラメーターを提供するuseContext=true
Build-Timeパラメーターを有効にする必要があります。検出/フラッシング動作。
例/詳細については、 batching.proto
ファイルと関連するテストを参照してください。
しかし、最終的な効果は、TS-ProtoがクライアントコールにSQL- / ORMスタイルN+1予防を提供できることです。 。
ts-proto
はprotoc
プラグインであるため、プロジェクトで直接、またはモノレポスキーマパイプライン、つまりイボッタのようなものであるか、つまり)によって実行されます。
package.json
にts-proto
追加します
npm install
実行してダウンロードします
次のようなplugin
パラメーターを使用してprotoc
呼び出します。
protoc -plugin = node_modules/ts-proto/protoc-gen-ts_proto ./batching.proto -i。
ts-proto
protobuf-gradle-pluginを使用してGradleで呼び出すこともできます。
protobuf { プラグイン{// `ts`は、未使用のプラグイン名、例えば` tsproto`ts { path = 'path/to/plugin'} } //このセクションは、プラグインオプションを提供する場合にのみ必要です。 all()。各{task-> task.plugins {//プラグインIDと宣言されたabovetsを一致させる必要があります{ オプション 'foo = bar'} } } } }
生成されたコードは、Gradleビルドディレクトリに配置されます。
--ts_proto_opt=globalThisPolyfill=true
で、ts-protoにはglobalthisのポリフィルが含まれます。
デフォルトはfalse
です。つまり、 globalThis
が利用可能であると想定しています。
--ts_proto_opt=context=true
で、サービスにはゴースタイルのctx
パラメーターがあり、トレース/ロギング/などに役立ちます。パフォーマンスの理由により、Nodeのasync_hooks
APIを使用していない場合。
--ts_proto_opt=forceLong=long
では、64ビットのすべての数値がLong
インスタンスとして解析されます(長いライブラリを使用)。
--ts_proto_opt=forceLong=string
で、すべての64ビット番号が文字列として出力されます。
--ts_proto_opt=forceLong=bigint
で、すべての64ビット番号がBigInt
として出力されます。このオプションは、 long
ライブラリを使用してprotobuf.js
内で内部的にエンコード/デコードしますが、TS-Protoで生成されたコードのBigInt
に変換されます。
デフォルトの動作はforceLong=number
です。これは内部的にlong
ライブラリを使用してワイヤー上の値をエンコード/デコードします(したがって、 util.Long = Long
line in your output)が、 long
値をnumber
に変換しますあなたのために自動的に。この変換を行うと、64ビット値がnumber
として正しく保存できるよりも大きい場合、ランタイムエラーがスローされることに注意してください。
--ts_proto_opt=useJsTypeOverride
で、フィールドで指定されたfieldoption.jstypeとして64ビット番号が出力されます。これは、提供されたforceLong
オプションよりも優先されます。
--ts_proto_opt=esModuleInterop=true
変更出力がesModuleInterop
に準拠します。
具体的には、 Long
輸入品はimport Long from 'long'
import * as Long from 'long'
輸入品として生成されます。
--ts_proto_opt=env=node
またはbrowser
、またはboth
で、ts-protoは出力で環境固有の仮定を行います。これはboth
になり、環境固有の仮定はありません。
node
を使用すると、 Uint8Array
からBuffer
までのbytes
の種類が変更され、一般的にBuffer
を使用するノードエコシステムとの統合が容易になります。
現在、 browser
「 node
ではない」以外の特定の動作はありません。それはおそらくすぐに/ある時点ででしょう。
--ts_proto_opt=useOptionals=messages
(メッセージフィールド用)または - ts_proto_opt = useoptionals field: Message | undefined
--ts_proto_opt=useOptionals=all
(メッセージおよびスカラーフィールド用)、フィールドはオプションキーとして宣言されますfield?: Message
field: Message | undefined
。
ts-protoはuseOptionals=none
にデフォルトです。
タイプミスの予防のために、オプションのフィールドにより、余分なフィールドがメッセージに簡単に滑り込むことができます(正確なタイプを取得するまで)、つまり:
インターフェイスSomeMessage { FirstName:文字列; lastname:string;} // typoconst data = {firstName: "a"、lasttypo: "b"}; // useoptionals = noneで宣言された、これは正しくコンパイルできません。 「lastname」がオプションであった場合、それはメッセージを構成しません:somemessage = {... data};
一貫したAPIの場合、 SomeMessage.lastName
がオプションのlastName?
、次に、読者は2つの空の条件をチェックする必要があります。a) lastName
undefined
(b/cはメモリ内で作成されて解除されたまま)、またはb) lastName
の空の文字列(b/cはワイヤーからのSomeMessage
読みます。 proto3仕様、初期化されたlastName
から空の文字列)?
適切な初期化を確保するために、後でSomeMessage.middleInitial
が追加された場合、それはオプションの中middleInitial?
、生産コードに多くのコールサイトがあるかもしれません。これは、有効なSomeMessage
を作成するためにmiddleInitial
通過するはずですが、そうではありません。
したがって、タイプミスプレベーション、読者の矛盾、適切な初期化の間に、TS-PROTOは、 useOptionals=none
「最も安全な」オプションとして使用することをお勧めします。
とはいえ、このアプローチでは、作家/クリエイターがすべてのフィールドを設定する必要があります( fromPartial
and create
これに対処するためのものですが)。したがって、オプションのキーを使用する場合は、 useOptionals=messages
またはuseOptionals=all
を設定できます。
( useOptional
に関する議論については、この問題とこの問題を参照してください。)
メッセージを初期化するときにタイプミスを防ぎます
読者に最も一貫したAPIを提供します
すべてのフィールドで生産メッセージが適切に初期化されるようにします。
--ts_proto_opt=exportCommonSymbols=false
、 DeepPartial
やprotobufPackage
などのユーティリティタイプはexport
されません。
これにより、生成された出力、つまり./fooおよびimport * from ./bar
import * from ./foo
のバレルインポートの作成が可能になります。
複数の*.proto
ファイルで同じメッセージ名がある場合でも、インポート競合が表示されることに注意してください。
--ts_proto_opt=oneof=unions
では、 oneof
フィールドがADTSとして生成されます。
「1つの処理」セクションを参照してください。
with with --ts_proto_opt=unrecognizedEnumName=<NAME>
enumsには、 unrecognizedEnumValue
オプションの値を持つkey <NAME>
が含まれます。
デフォルトは認識されてUNRECOGNIZED
。
with --ts_proto_opt=unrecognizedEnumValue=<NUMBER>
enumsには、 <NUMBER>
の値を持つunrecognizedEnumName
オプションによって提供されるキーが含まれます。
デフォルトは-1
です。
--ts_proto_opt=unrecognizedEnum=false
enumsには、認識さunrecognizedEnumName
および承認unrecognizedEnumValue
eNumの価値が含まれていないことは含まれていません。
--ts_proto_opt=removeEnumPrefix=true
生成されたenumsは、メンバーから列挙名を削除します。
FooBar.FOO_BAR_BAZ = "FOO_BAR_BAZ"
FooBar.BAZ = "FOO_BAR_BAZ"
を生成します "
--ts_proto_opt=lowerCaseServiceMethods=true
service.findFoo
service.FindFoo
--ts_proto_opt=snakeToCamel=false
で、フィールドはメッセージキーとtoJSON
/ fromJSON
メソッドの両方でヘビのケースを維持します。
snakeToCamel
、文字列の_
-delimitedリストとして設定することもできます(コンマkeys
フラグが区切られたjson
に予約されています)、すなわち--ts_proto_opt=snakeToCamel=keys_json
。キャメルケース。
空の文字列、すなわちsnakeToCamel=
は、メッセージキーとJSON
キーの両方をスネークケースとして保持します( snakeToCamel=false
と同じです)。
json_name
属性を使用するには、 json
使用する必要があることに注意してください。
デフォルトの動作はkeys_json
です。つまり、両方ともキャメルケースがあり、 json_name
が設定されている場合は使用されます。
--ts_proto_opt=outputEncodeMethods=false
、 Message.encode
and Message.decode
メソッドProtoBuf-Encoded/バイナリデータを操作するためのメソッドは出力されません。
これは、「のみタイプ」が必要な場合に便利です。
--ts_proto_opt=outputJsonMethods=false
、 Message.fromJSON
およびMessage.toJSON
Jsonコードデータを操作するためのメソッドは出力されません。
これは、「のみタイプ」が必要な場合にも便利です。
--ts_proto_opt=outputJsonMethods=to-only
and --ts_proto_opt=outputJsonMethods=from-only
から、 Message.toJSON
とMessage.fromJSON
メソッドの間で1つだけをエクスポートできます。
これは、TS-Protoを使用して、両方ではなくencode
またはdecode
ためだけに使用する場合に役立ちます。
--ts_proto_opt=outputPartialMethods=false
、 Message.fromPartial
and Message.create
メソッドは、部分的に形成されたオブジェクト/オブジェクトリテラルを受け入れるためのメソッドは出力されません。
--ts_proto_opt=stringEnums=true
で、生成された列挙型はintベースではなく文字列ベースになります。
これは、「のみタイプ」が必要であり、列挙を文字列としてシリアル化するように構成されたGRPC RESTゲートウェイを使用している場合に役立ちます。
( outputEncodeMethods=false
が必要です。)
--ts_proto_opt=outputClientImpl=false
を使用して、クライアント側(TWIRPではgrpc-web
の次のオプションを参照)を実装するクライアントの実装、つまりFooServiceClientImpl
使用して出力されません。
--ts_proto_opt=outputClientImpl=grpc-web
で、クライアントの実装、すなわちFooServiceClientImpl
は、実行時に @expbable-eng/grpc-webライブラリを使用してGRPC-webバックエンドにGRPCメッセージを送信します。
(これはGRPC-WEBランタイムのみを使用していることに注意してください。生成されたコードを使用する必要はありません。つまり、TS-Protoの出力はts-protoc-gen
出力を置き換えます。)
@improbable-eng/grpc-web
追加し、プロジェクトのpackage.json
にトランスポートを追加する必要があります。実用的な例については、 integration/grpc-web
ディレクトリを参照してください。 GRPC-WEB-Devtoolsとの統合については、#504も参照してください。
--ts_proto_opt=returnObservable=true
Promise<T>
Observable<T>
--ts_proto_opt=addGrpcMetadata=true
で、サービスメソッドの最後の引数は、コールに追加情報を含むGRPC Metadata
タイプを受け入れます(つまり、アクセストークン/など)。
( nestJs=true
が必要です。)
--ts_proto_opt=addNestjsRestParameter=true
で、サービスメソッドの最後の引数は、タイプのRESTパラメーターになります。このようにして、通常はnestjsで使用できるカスタムデコレータを使用できます。
( nestJs=true
が必要です。)
--ts_proto_opt=nestJs=true
を使用すると、デフォルトは変更され、nestjs protobuf実装のクライアント側とサーバー側の両方で使用できるNestjsプロトブフレンドリータイプとサービスインターフェイスが生成されます。詳細と実装の例については、nestjs readmeを参照してください。
具体的には、 outputEncodeMethods
、 outputJsonMethods
、およびoutputClientImpl
はすべて偽りになります。 lowerCaseServiceMethods
は真であり、 outputServices
無視されます。
addGrpcMetadata
、 addNestjsRestParameter
、およびreturnObservable
まだ虚偽であることに注意してください。
with --ts_proto_opt=useDate=false
、タイプのフィールドgoogle.protobuf.Timestamp
生成されたタイプのDate
を入力することはマッピングされません。詳細については、タイムスタンプを参照してください。
--ts_proto_opt=useMongoObjectId=true
、objectIdと呼ばれるタイプのフィールドは、[生成された型のmongodb.ObjectId
と型と呼ばれるフィールドと呼ばれるフィールドに構築されます。これには、プロジェクトがMongoDB NPMパッケージをインストールする必要があります。詳細については、ObjectIDを参照してください。
--ts_proto_opt=annotateFilesWithVersion=false
で、生成されたファイルには、ファイルの生成に使用されるprotoc
とts-proto
のバージョンは含まれません。このオプションは通常、ファイルが使用されるバージョンをリストするようにtrue
に設定されます。
--ts_proto_opt=outputSchema=true
で、メタタイピングが生成され、後で他のコードジェネレーターで使用できます。
--ts_proto_opt=outputSchema=no-file-descriptor
では、メタタイピングが生成されますが、生成されたスキーマにファイル記述子を含めません。これは、生成されたスキーマのサイズを最小限に抑えようとしている場合に役立ちます。
--ts_proto_opt=outputSchema=const
で、メタタイピングがas const
生成され、すべてのプロパティにタイプセーフアクセスが可能になります。 (TypeScript 4.9以降でのみ動作します。これは、 satisfies
オペレーターも使用するためです)。生成されたスキーマにファイル記述子を含めないようにno-file-descriptor
オプション( outputSchema=const,outputSchema=no-file-descriptor
)と組み合わせることができます。
--ts_proto_opt=outputTypeAnnotations=true
で、各メッセージには、完全に資格のある名前を含む$type
フィールドが与えられます。 --ts_proto_opt=outputTypeAnnotations=optional
interface
--ts_proto_opt=outputTypeAnnotations=static-only
を使用して、 interface
宣言から省略します。後者のオプションは、サーバーからの応答のランタイムタイプチェックに$type
フィールドを使用する場合に役立ちます。
--ts_proto_opt=outputTypeRegistry=true
で、完全に資格のある名前でメッセージタイプを解決するために使用できるタイプレジストリが生成されます。また、各メッセージには、完全に資格のある名前を含む$type
フィールドが与えられます。
--ts_proto_opt=outputServices=grpc-js
を使用すると、TS-ProtoはGRPC-JS形式でサービス定義とサーバー /クライアントスタブを出力します。
--ts_proto_opt=outputServices=generic-definitions
では、TS-PROTOはジェネリック(フレームワークと依存)サービス定義を出力します。これらの定義には、リクエストと応答タイプへのリンクを備えた各メソッドの記述子が含まれています。これにより、実行時にサーバーとクライアントのスタブを生成し、コンパイル時に強力なタイプを生成できます。このアプローチを使用するライブラリの例は、NICE-GRPCです。
--ts_proto_opt=outputServices=nice-grpc
、ts-protoはnice-grpcのサーバーとクライアントスタブを出力します。これは、一般的な定義と一緒に使用する必要があります。つまり、2つのオプションを指定する必要があります。AutputServices outputServices=nice-grpc,outputServices=generic-definitions
。
--ts_proto_opt=metadataType=Foo@./some-file
、ts-protoは汎用(フレームワークと存在する)メタデータフィールドを汎用サービス定義に追加します。
--ts_proto_opt=outputServices=generic-definitions,outputServices=default
、TS-PROTOは、一般的な定義とインターフェイスの両方を出力します。これは、インターフェイスに頼りたい場合に役立ちますが、実行時にはいくつかの反射機能もあります。
--ts_proto_opt=outputServices=false
、または=none
では、ts-protoはサービス定義を出力しません。
--ts_proto_opt=rpcBeforeRequest=true
、ts-protoは、signature: beforeRequest(service: string, message: string, request: <RequestType>)
を使用してRPCインターフェイス定義に関数定義を追加します。また、自動的にoutputServices=default
を設定します。各サービスのメソッドは、リクエストを実行する前にbeforeRequest
を呼び出します。
--ts_proto_opt=rpcAfterResponse=true
、ts-protoは、signature: afterResponse(service: string, message: string, response: <ResponseType>)
を使用してRPCインターフェイス定義に関数定義を追加します。また、自動的にoutputServices=default
を設定します。各サービスのメソッドは、応答を返す前にafterResponse
後に呼び出します。
--ts_proto_opt=rpcErrorHandler=true
、ts-protoは、signerature: handleError(service: string, message: string, error: Error)
を使用して、rpcインターフェイス定義に関数定義を追加します。また、自動的にoutputServices=default
を設定します。
--ts_proto_opt=useAbortSignal=true
で、生成されたサービスは、RPC呼び出しをキャンセルするためにAbortSignal
を受け入れます。
--ts_proto_opt=useAsyncIterable=true
使用すると、生成されたサービスはObservable
ではなく非AsyncIterable
です。
-ts_proto_opt protoc
google/protobuf/*
--ts_proto_opt=emitImportedFiles=false
protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto my_message.proto google/protobuf/duration.proto
--ts_proto_opt=fileSuffix=<SUFFIX>
で、TS-PROTOは指定された接尾辞を使用して生成されたファイルを発します。 fileSuffix=.pb
を使用したhelloworld.proto
ファイルは、 helloworld.pb.ts
として生成されます。これは、他のプロトックプラグインでの一般的な動作であり、生成されたすべてのファイルをすばやくグローブする方法を提供します。
--ts_proto_opt=importSuffix=<SUFFIX>
で、ts-protoは指定されたサフィックスを使用してファイルインポートを発します。 fileSuffix=.js
を使用したhelloworld.ts
のインポートはimport "helloworld.js"
を生成します。デフォルトは、ファイル拡張子なしでインポートすることです。 TypeScript 4.7.x以降でサポートされています。
--ts_proto_opt=enumsAsLiterals=true
as const
--ts_proto_opt=useExactTypes=false
を使用して、生成されたfromPartial
とcreate
メソッドは正確なタイプを使用しません。
デフォルトの動作は、 useExactTypes=true
であり、それはfromPartial
になり、その引数に正確なタイプを使用create
て、タイプスクリプトを不明なプロパティを拒否するようにします。
--ts_proto_opt=unknownFields=true
で、すべての不明なフィールドは解析され、バッファーの配列として出力されます。
--ts_proto_opt=onlyTypes=true
では、型のみが放出され、 long
およびprotobufjs/minimal
のインポートが除外されます。
これはoutputJsonMethods=false,outputEncodeMethods=false,outputClientImpl=false,nestJs=false
の設定と同じです
--ts_proto_opt=usePrototypeForDefaults=true
で、生成されたコードはObject.create
で新しいオブジェクトをラップします。
これにより、コードはHazzerチェックを行い、デフォルト値が適用されたときに検出できます。これは、Proto3のWireにデフォルト値を置かないという動作により、通常、Proto2メッセージとの相互作用にのみ役立ちます。
有効にすると、デフォルト値はプロトタイプから継承されるため、コードはobject.keys()を使用できます。
示されているように、これはobject.keysにはセットバイデフォルトフィールドが含まれないことを意味します。したがって、メッセージキーを一般的に繰り返すコードがある場合、プロトタイプから継承されたキーを繰り返す必要があります。
--ts_proto_opt=useJsonName=true
、json_nameプロトファイルで定義されたjson_name
、メッセージフィールド名の代わりに使用されます。
--ts_proto_opt=useJsonWireFormat=true
で、生成されたコードは、プロトブフメッセージのJSON表現を反映します。
onlyTypes=true
が必要です。 useDate=string
and stringEnums=true
このオプションは、JSONとしてシリアル化されたMarshalling/Marshalling Protobufメッセージで直接使用できるタイプを生成することです。 Scalar値のデフォルト値を送信するためにGRPCゲートウェイが必要ないため、 useOptionals=all
設定することもできます。
--ts_proto_opt=useNumericEnumForJson=true
で、JSONコンバーター( toJSON
)は、文字列リテラルではなく、enum値をintとしてエンコードします。
--ts_proto_opt=initializeFieldsAsUndefined=false
で、すべてのオプションのフィールドイニシャルは生成されたベースインスタンスから省略されます。
--ts_proto_opt=disableProto2Optionals=true
で、proto2ファイルのすべてのオプションフィールドはオプションに設定されません。このフラグは、主にTS-ProtoのProto2ファイルのレガシー処理を維持するためのものであり、変化を避けるためであり、その結果、前進することを意図していないことに注意してください。
--ts_proto_opt=disableProto2DefaultValues=true
で、デフォルト値を指定するproto2ファイルのすべてのフィールドは、実際にそのデフォルト値を使用しません。このフラグは、主にTS-ProtoのProto2ファイルのレガシー処理を維持するためのものであり、変化を避けるためであり、その結果、前進することを意図していないことに注意してください。
--ts_proto_opt=Mgoogle/protobuf/empty.proto=./google3/protobuf/empty
./google/protobuf/empty.ts
オーバーライドされた値を反映しています。
Mfoo/bar.proto=@myorg/some-lib
/some-libは、 foo/bar.proto
インポートをimport ... from '@myorg/some-lib'
にマッピングします。
Mfoo/bar.proto=./some/local/lib
foo/bar.proto
インポートをimport ... from './some/local/lib'
。
Mfoo/bar.proto=some-modules/some-lib
foo/bar.proto
import ... from 'some-module/some-lib'
マッピングします。
注:使用が蓄積されるため、 --ts_proto_opt=M... --ts_proto_opt=M...
(マッピングごとに1つのts_proto_opt
)の形式で複数の値が予想されます。
注:マッピングされたインポートと一致するプロトファイルは生成されません。
--ts_proto_opt=useMapType=true
で、protobuf map<key_type, value_type>
の生成コードは、javascriptマップタイプを使用するMap<key_type, value_type>
になります。
デフォルトの動作はuseMapType=false
です。これにより{[key: key_type]: value_type}
のようなkey-valueペアを使用して、protobuf map<key_type, value_type
のコードを生成します。
--ts_proto_opt=useReadonlyTypes=true
readonly
with --ts_proto_opt=useSnakeTypeName=false
は、タイプからヘビのケーシングを削除します。
例Protobuf
メッセージボックス{メッセージ要素{メッセージ画像{enum alignment {left = 1; Center = 2; 右= 3; } } } }
デフォルトでは、これが有効になっており、 Box_Element_Image_Alignment
の種類を生成します。このオプションを無効にすることにより、生成されるタイプはBoxElementImageAlignment
になります。
--ts_proto_opt=outputExtensions=true
で、生成されたコードにはproto2拡張子が含まれます
拡張エンコード/デコードメソッドは、 outputEncodeMethods
オプションに準拠しており、 unknownFields=true
の場合、拡張可能なメッセージに対してsetExtension
およびgetExtension
メソッドが作成され、 outputEncodeMethods
(setextension = encode、getextension = decode)にも準拠します。
--ts_proto_opt=outputIndex=true
で、indexファイルはprotoパッケージ名空間に基づいて生成されます。
これにより、共通のシンボルの名前の衝突を避けるために、 exportCommonSymbols
無効になります。
--ts_proto_opt=emitDefaultValues=json-methods
では、生成されたトジソン法は、jsonフィールドとして0
や""
などのスカラーを排出します。
--ts_proto_opt=comments=false
で、コメントはprotoファイルから生成されたコードにコピーされません。
--ts_proto_opt=bigIntLiteral=false
で、生成されたコードは、bigintリテラルの場合は0n
の代わりにBigInt("0")
を使用します。 「ES2020」よりも古いものに設定された「ターゲット」コンパイラオプションがタイプスクリプトによってサポートされていません。
--ts_proto_opt=useNullAsOptional=true
、 undefined
値はnull
に変換され、 .proto
ファイルでoptional
ラベルを使用すると、フィールドにもundefined
タイプがあります。例えば:
--ts_proto_opt=typePrefix=MyPrefix
では、生成されたインターフェイス、列挙、および工場には、名前にMyPrefix
の接頭辞があります。
--ts_proto_opt=typeSuffix=MySuffix
では、生成されたインターフェイス、enums、および工場には、名前にMySuffix
の接尾辞があります。
メッセージprofileinfo {int32 id = 1; string bio = 2; string phone = 3; }メッセージ部門{int32 id = 1; string name = 2; } message user {int32 id = 1; string username = 2;/* profileInfoはタイプスクリプトでオプションになります。タイプはprofileinfo | null |未定義は、プロファイルに価値を提供したくない場合に必要です。 */optional ProfileInfoプロファイル= 3;/*部門は部門の種類またはnullのみを受け入れるため、利用可能な値がない場合はnullを渡す必要があることを意味します。 */部門= 4; }
生成されたインターフェイスは次のとおりです。
インターフェイスProfileInfoをエクスポートする{ ID:番号; バイオ:文字列; 電話:文字列;}インターフェイス部門のエクスポート{ ID:番号; 名前:文字列;}インターフェイスユーザーをエクスポートする{ ID:番号; ユーザー名:文字列; プロフィール?:ProfileInfo | null |未定義; //これを確認してください 部門:部門|ヌル; //これをチェックしてください}
--ts_proto_opt=noDefaultsForOptionals=true
、 undefined
原始値は、protobuf仕様に従ってデフォルトではありません。さらに、標準の動作とは異なり、フィールドが標準のデフォルト値に設定されている場合、エンコードされ、ワイヤー上で送信され、未定義の値と区別されます。たとえば、メッセージがブール値を設定しない場合、通常、これはデフォルトでfalse
になります。
このオプションにより、ライブラリは、square/blockによって維持および使用されるワイヤの実装を互換性のある方法で動作させることができます。注:このオプションは、このオプションが有効になっている場合、WireまたはTS-Protoを使用して生成された他のクライアント/サーバーコードと組み合わせてのみ使用する必要があります。
Nestjsと一緒に作業する素晴らしい方法があります。 ts-proto
、コントローラー、クライアント用のinterfaces
とdecorators
生成します。詳細については、nestjs readmeを参照してください。
Protoファイルの変更ごとにts-proto
実行する場合は、Chokidar-Cliなどのツールを使用して、 package.json
のスクリプトとして使用する必要があります。
「proto:generate ":" protoc --ts_proto_out =。./<proto_name>/<proto_name> .proto - ts_proto_opt = esmoduleinterop = true "、" proto:watch ":" chokidar "**/*。proto" - c "npm run proto:generate" "
ts-proto
はRPCフレームワーク不可欠なものです - データソースとの間でデータを送信する方法はあなた次第です。生成されたクライアントの実装はすべて、 rpc
パラメーターを期待しています。このタイプは次のように定義されています。
インターフェイスrpc { request(service:string、method:string、data:uint8array):Promise <uint8array>;}
GRPCを使用している場合、簡単な実装が次のようになります。
const conn = new grpc.client( 「LocalHost:8765」、 grpc.credentials.createInsecure()); type rpcimpl =(service:service:string、method:string、data:uint8array)=> promise <uint8array>; const sendrequest:rpcimpl =(service、method、data)=> {{ // grpcで従来、リクエストパスのように見えます // "package.names.servicename/methodname"、 //そのような文字列を構築します const path = `/$ {service}/$ {method}`; 新しい約束を返します((Resolve、拒否)=> {// makeUnaryRequestはコールバックで結果(およびエラー)を送信します//これを約束に変換します! (err){return reject(err);} resolve(res);}; function passthrough(angy:any){return argument;} // 、resultCallback); });}; const rpc:rpc = {request:sendRequest};
スポンサーへの称賛:
Ngrokは、TS-Protoの最初のGRPC-WEBサポートに資金を提供しました。
TS-Protoのカスタマイズや会社の優先サポートが必要な場合は、電子メールで私をpingすることができます。
このセクションでは、TS-Protoに直接貢献する方法について説明します。つまり、 protoc
でts-proto
を実行したり、生成されたTypeScriptを使用したりする必要はありません。
要件
Docker
yarn
- npm install -g yarn
設定
以下のコマンドは、 Dockerがインストールされていることを想定しています。 OS Xを使用している場合は、 Coreutilsをインストールし、 brew install coreutils
。
最新のコードについては、リポジトリをご覧ください。
yarn install
実行して、依存関係をインストールします。
yarn build:test
テストテストファイルを生成します。
これにより、次のコマンドが実行されます。
proto2ts
- integration/**/*.proto
ファイルでts-proto
を実行して.ts
ファイルを生成します。
proto2pbjs
- 互換性をテストするためにpbjs
を使用して参照実装を生成します。
yarn test
を実行します
ワークフロー
ユースケースの統合テストを追加/更新します
また、 yarn watch
ランニングを残すこともできます。
必要なts_proto_opt
paramsを使用して、新しいintegration/your-new-test/parameters.txt
を作成します
最小限のintegration/your-new-test/your-new-test.proto
スキーマを作成して、ユースケースを再現します
ユースケースに十分近い既存のintegration/*
テストを見つけるか、EGには、ユースケースを再現するために必要なts_proto_opt
パラメーションに一致するparameters.txt
があります。
新しい統合テストを作成する場合:
your-new-test.proto
または既存のintegration/*.proto
ファイルに変更された後、 yarn proto2bin
を実行します
integration/your-new-test/some-test.ts
ユニットテストを追加/更新します。
ts-proto
コード生成ロジックを変更します。
または、 yarn proto2ts your-new-test
て、特定のテストを再コデーブします
再びyarn watch
ランニングを残しても、「正しいことをするだけです」
最も重要なロジックは、SRC/main.tsにあります。
src yarn proto2ts
src/*.ts
yarn test
実行して変更を確認します既存のすべてのテストに合格します
PRをコミットして送信します
生成されたコードをチェックインすることが眉をひそめることがありますが、TS-PROTOの主な仕事がコードを生成することであることを考えると、PRSのコードゲンdiffが役立つのは役に立ちます
yarn format
実行して、TypeScriptファイルをフォーマットします。
必ずすべての*.proto
、 *.bin
、および*.ts
ファイルをintegration/your-new-test
でgit add
プロジェクトでテストします
手動でyarn build
実行する限り、 yarn add ts-proto@./path/to/ts-proto
実行することにより、独自のプロジェクトでローカルTS-Protoの変更をテストできます。
Dockerized Protoc
リポジトリには、docker-compose.ymlで構成されているDockerizedバージョンのprotoc
が含まれています。
既知のバージョンのprotoc
使用してプラグインを手動で呼び出す場合に役立ちます。
使用法:
#シェルにProtoc Airasを含めます。Aliase.sh#通常どおりProtocを実行します。 TS-PROTOディレクトリは/TS-PROTO.PROTOC --PLUGIN =/TS-PROTO/Protoc-Gen-TS_Proto - TS_Proto_out =。/output -i =。/protos./8protoc/* .proto#またはあなたのプラグインパスを指定するTS-Protocエイリアスを使用します。
すべてのパスは、ホストの現在の作業ディレクトリ内の相対パスでなければなりません。 ../
許可されていません
Dockerコンテナ内では、プロジェクトルートへの絶対パスは/ts-proto
です
コンテナは、現在の作業ディレクトリを/host
に取り付け、作業ディレクトリとして設定します。
aliases.sh
が調達されると、任意のフォルダーでprotoc
コマンドを使用できます。
TS/ES6モジュール名はProtoパッケージです
fromJSON
/ toJSON
での持続時間の文字列ベースのエンコードをサポートする
oneof=unions-value
2.0のデフォルトの動作にします
おそらく2.0でforceLong
デフォルトを変更すると、デフォルトでforceLong=long
に変更する必要があります
esModuleInterop=true
2.0のデフォルトにします
デフォルトでは、TS-PROTOは、メッセージの「完全に」 oneof
フィールドをモデル化します。たとえば、次のようなメッセージがあります。
メッセージfoo {oneof tay_field {string field_a = 1;文字列field_b = 2; } }
2つのフィールドでFoo
タイプを生成します: field_a: string | undefined;
およびfield_b: string | undefined
。
この出力を使用すると、 if object.field_a
とif object.field_b
両方を確認する必要があります。一方を設定した場合は、他のものを解明することを忘れないでください。
代わりに、 oneof=unions-value
オプションを使用することをお勧めします。これにより、出力が代数データ型/ADTに変更されます。
yourmessageインターフェイス{ どちらかのフィールド?:{$ case: "field_a";値:文字列} | {$ case: "field_b";値:文字列};}
これは、一度に単一の値を持つことができるいずれかeitherField
フィールドに値が保存されるため、一度にfield_a
またはfield_b
「設定」の1つのみを自動的に強制するためです。
(いずれかのeitherField
オプションであることに注意してください。プロトブフのb/c oneof
は「最大1つのフィールド」が設定されていることを意味し、フィールドの1つを設定する必要があるという意味ではありません。)
TS-Protoの現在廃止されていない2.xリリースでは、 oneof=unions-value
デフォルトの動作になります。
また、各オプションにフィールド名が含まれている組合を生成するoneof=unions
オプションもあります。
yourmessageインターフェイス{ どちらかのフィールド?:{$ case: "field_a"; field_a:string} | {$ case: "field_b"; field_b:string};}
これは、コードとタイプを作成して複数のONESオプションを処理するのが難しい場合があるため、推奨されなくなりました。
次のヘルパータイプにより、 oneof=unions
から生成されたタイプで作業しやすくなる場合がありますが、 oneof=unions-value
使用する場合は必要ありません。
/** 1つのフィールドからすべてのケース名を抽出します。 */Type Oneofcases <t> = t extends {$ case:推測u extends string}? u:unnewer;/** 1つのフィールドからすべての値タイプの結合を抽出します*/type oneofvalues <t> = t extends {$ case:us u extends string; [キー:文字列]:不明}? T [u]:決して;/**そのフィールド名に基づいて特定のタイプの1つのケースを抽出します*/タイプのOneofcase <t、kはOneofcase <t >> = t拡張{ $ case:k; [キー:文字列]:不明;} ? t :決して;/** 1つのフィールドから特定のタイプの値タイプを抽出します*/type oneofvalue <t、kはoneofcases <t >> = t extends { $ case:推測uはkを拡張します。 [キー:文字列]:不明;} ? t [u] : 一度もない;
比較のために、 oneof=unions-value
の同等物:
/** 1つのフィールドからすべてのケース名を抽出します。 */タイプOneofcases <t> = t ['$ case'];/** 1つのフィールドからすべての値タイプの結合を抽出します*/type oneofvalues <t> = t ['value'];/**抽出そのフィールド名に基づいた特定のタイプの1つのケース */タイプOneofcase <t、kはOneofcase <t >> = t拡張{ $ case:k; [キー:文字列]:不明;} ? t :決して;/** 1つのフィールドから特定のタイプの値タイプを抽出します*/type oneofvalue <t、kはoneofcases <t >> = t extends { $ case:推測uはkを拡張します。 値:不明;} ? t [u] : 一度もない;
Core Protobuf(およびts-proto
と同様)では、デフォルト値または等しい値がワイヤー上に送信されない値が送信されません。
たとえば、メッセージのデフォルト値はundefined
です。プリミティブタイプは、自然なデフォルト値を取得します。たとえば、 string
は''
、 number
は0
などです。
Protobufは、古いエージェントによって省略された場合でも、プリミティブフィールドには常に価値があるため、順方向の互換性を可能にするため、この動作を選択/強制します。
これは良いことですが、デフォルト値と未解決の値をts-proto
フィールドで区別できないことも意味します。それは基本的にプロトブフの仕組みです。
セット/リンクセットを検出できるプリミティブフィールドが必要な場合は、ラッパータイプを参照してください。
エンコード /デコード
ts-proto
ProtoBUFルールに従い、バイナリ形式でシリアル化されたときに出力からそれらを省略しながら、デコード時に設定フィールドのデフォルト値を常に返します。
syntax = "proto3"; message foo {string bar = 1; }
protobufbytes; //これは、Protobuf binary formatfoo.decode(protobufbytes)の空のfooオブジェクトであると仮定します。 // => {bar: ''}
foo.encode({bar: ""}); // => {}、Protobufバイナリ形式で空のfooオブジェクトを書き込みます
json / tojsonから
JSONの読み取りは、デフォルト値も初期化します。送信者は、未解決のフィールドを省略するか、デフォルト値に設定する場合があるため、 fromJSON
を使用して入力を正規化します。
foo.fromjson({}); // => {bar: ''} foo.fromjson({bar: ""}); // => {bar: ''} foo.fromjson({bar: "baz"}); // => {bar: 'baz'}
JSONを書くとき、 ts-proto
デフォルト値に設定されている非セットフィールドとフィールドを省略することにより、メッセージを正規化します。
foo.tojson({}); // => {} foo.tojson({bar:undefined}); // => {} foo.tojson({bar: ""}); // => {} - 注:expectionfoo.tojson({bar: "baz"})として、デフォルト値を省略します。 // => {bar: 'baz'}
Protobufには、「よく知られたタイプ」と呼ばれるいくつかの事前定義されたメッセージ定義が付属しています。それらの解釈はProtoBUF仕様によって定義され、ライブラリはこれらのメッセージをターゲット言語の対応するネイティブタイプに変換することが期待されています。
ts-proto
現在、これらのメッセージを対応するネイティブタイプに自動的に変換しています。
boolean
Uint8Array
google.protobuf.doublevalue⇆ number
google.protobuf.fieldmask⇆string string[]
google.protobuf.floatvalue⇆ number
google.protobuf.int32value⇆ number
google.protobuf.int64value⇆ number
google.protobuf.listvalue any[]
google.protobuf.uint32value⇆ number
google.protobuf.uint64value⇆ number
google.protobuf.stringvalue⇆ string
google.protobuf.value any
( number | string | boolean | null | array | object
)
google.protobuf.struct⇆ { [key: string]: any }
ラッパータイプは、単一のプリミティブフィールドを含むメッセージであり、 import "google/protobuf/wrappers.proto"
.proto
ファイルにインポートできます。
これらはメッセージであるため、デフォルト値はundefined
ため、ラッパータイプを使用する場合、デフォルト値とデフォルト値を区別できます。 ts-proto
これらのフィールドを<primitive> | undefined
として生成します<primitive> | undefined
。
例えば:
// protobufsyntax = "proto3"; Import "Google/protobuf/wrappers.proto"; message examplemessage {google.protobuf.stringvalue name = 1; }
// typeScriptInterface examplemessage { 名前:文字列|未定義;}
メッセージをエンコードすると、プリミティブ値が対応するラッパータイプに戻されます。
ExamPlemessage.Encode({name: "foo"}); // => {name:{value: 'foo'}}、binary
Tojsonを呼び出すとき、ラッパータイプはJSONで慣用的であるため、値は変換されません。
Examplemessage.tojson({name: "foo"}); // => {name: 'foo'}
JSONには事前に不明な値が含まれている可能性があるため、Protobufの言語とタイプはすべてのJSON値を表すのに十分ではありません。このため、Protobufは任意のJSON値を表すためにいくつかの追加のタイプを提供します。
これらはstructタイプと呼ばれ、 import "google/protobuf/struct.proto"
.proto
ファイルにインポートできます。
google.protobuf.value⇆ any
これは最も一般的なタイプであり、任意のJSON値(IE number | string | boolean | null | array | object
)を表すことができます。
google.protobuf.listvalue any[]
JSONアレイを表す
google.protobuf.struct⇆ { [key: string]: any }
JSONオブジェクトを表す
ts-proto
、これらの構造体タイプと対応するJSONタイプの間で自動的に前後に変換されます。
例:
// protobufsyntax = "proto3"; Import "Google/protobuf/struct.proto"; message Examplemessage {google.protobuf.value Anyty Anyty = 1; }
// typeScriptInterface examplemessage { 何でも:任意の|未定義;}
メッセージに埋め込まれたJSON値をエンコードすると、それをstructタイプに変換します。
Examplemessage.Encode({Anything:{name: "hello"}});/*次の構造を出力します。 value {stringvalue = "hello"}]}}}}*/examplemessage.encode({Anything:true});/* protobufバイナリ形式でエンコードされた次の構造を出力します:{anything:value {boolvalue = true}}}}} */
google.protobuf.Timestamp
の表現は、 useDate
フラグで構成可能です。 useJsonTimestamp
フラグは、 useDate
ている場合の精度をfalse
制御します。
Protobufよく知られたタイプ | default/ useDate=true | useDate=false | useDate=string | useDate=string-nano |
---|---|---|---|---|
google.protobuf.Timestamp | Date | { seconds: number, nanos: number } | string | string |
使用する場合、 useDate=false
およびuseJsonTimestamp=raw
タイムスタンプは{ seconds: number, nanos: number }
として表されますが、ナノ秒の精度があります。
使用する場合、 useDate=string-nano
タイムスタンプは、ナノ秒の精度1970-01-01T14:27:59.987654321Z
のISO文字列として表され、変換のためにNano-Dateライブラリに依存しています。プロジェクトにインストールする必要があります。
数字は、デフォルトではプレーンJavaScript number
sであると想定されています。
これは、 int32
やfloat
などのプロトブフタイプには適していますが、 int64
のような64ビットタイプはJavaScriptのnumber
タイプで100%表現することはできません。INT64 int64
number
よりも大きい/小さいためです。
TS-Protoのデフォルト構成( forceLong=number
)は、64ビットフィールドにnumber
を使用し、値(実行時に)がNumber.MAX_SAFE_INTEGER
よりも大きい場合にエラーをスローすることです。
64ビット /より高いMAX_SAFE_INTEGER
値を使用すると予想される場合は、TS-Proto forceLong
オプションを使用して、長いnpmパッケージを使用して64ビット値の全範囲をサポートします。
Protobuf Numberタイプは、 forceLong
構成オプションに基づいてJavaScriptタイプにマッピングされます。
プロトブフ番号タイプ | デフォルト/ forceLong=number | forceLong=long | forceLong=string |
---|---|---|---|
ダブル | 番号 | 番号 | 番号 |
フロート | 番号 | 番号 | 番号 |
INT32 | 番号 | 番号 | 番号 |
INT64 | 番号* | 長さ | 弦 |
UINT32 | 番号 | 番号 | 番号 |
UINT64 | 番号* | 符号なしの長い | 弦 |
SINT32 | 番号 | 番号 | 番号 |
SINT64 | 番号* | 長さ | 弦 |
固定32 | 番号 | 番号 | 番号 |
固定64 | 番号* | 符号なしの長い | 弦 |
sfixed32 | 番号 | 番号 | 番号 |
sfixed64 | 番号* | 長さ | 弦 |
ここで、(*)は、実行時にエラーを投げる可能性があることを示します。
必要なプリミティブ:AS-IS、IE string name = 1
を使用します。
オプションのプリミティブ:ラッパータイプ、つまりStringValue name = 1
を使用します。
必要なメッセージ:利用できません
オプションのメッセージ:AS-IS、つまりSubMessage message = 1
を使用します。