ts-proto
แปลงไฟล์.proto
ของคุณเป็นไฟล์ typeitive typescript ที่พิมพ์อย่างรุนแรง!
การเปิดตัว 2.x ของ TS-Proto อพยพต่อ protobuf ระดับต่ำที่การ encode
และวิธี decode
ใช้จากการใช้งาน แต่อายุและนิ่งและนิ่ง, แพ็คเกจ protobufjs
ไปยัง @bufbuild/protobuf
หากคุณใช้วิธี encode
และ decode
เท่านั้นสิ่งนี้ควรเป็นการเปลี่ยนแปลงที่ไม่ทำลาย
อย่างไรก็ตามหากคุณใช้รหัสใด ๆ ที่ใช้ Writer
protobufjs
หรือคลาส 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 ขั้นพื้นฐาน
ผู้สนับสนุน
การพัฒนา
สมมติฐาน
สิ่งที่ต้องทำ
การจัดการหนึ่งครั้ง
ค่าเริ่มต้นและฟิลด์ UNSET
ประเภทที่รู้จักกันดี
ประเภทเสื้อคลุม
ประเภท JSON (ประเภทโครงสร้าง)
การประทับเวลา
ประเภทหมายเลข
สถานะปัจจุบันของค่าเสริม
TS-PROTO สร้างประเภท typeScript จาก schemas protobuf
เช่นให้ person.proto
สคีมาเช่น:
บุคคลข้อความ {ชื่อสตริง = 1; -
TS-PROTO จะสร้างไฟล์ person.ts
เช่น:
คนอินเทอร์เฟซ { ชื่อ: String} const person = { เข้ารหัส (บุคคล): นักเขียน {... } decode (reader): บุคคล {... } tojson (บุคคล): ไม่ทราบ {... } fromjson (data): บุคคล {... }}
นอกจากนี้ยังรู้เกี่ยวกับบริการและจะสร้างประเภทสำหรับพวกเขาเช่นกันเช่น:
อินเทอร์เฟซส่งออก 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
มีชื่อตามคำต่อท้ายของชื่อปลั๊กอินเช่น "ts_proto" คำต่อท้ายใน-plugin = _out
--plugin=./node_modules/.bin/protoc-gen-ts_proto
พารามิเตอร์ ตามการประชุม CLI ของ protoc
)
บน Windows ให้ใช้ protoc --plugin=protoc-gen-ts_proto=".node_modules.binprotoc-gen-ts_proto.cmd" --ts_proto_out=. ./simple.proto
(ดู #93)
ตรวจสอบให้แน่ใจว่าคุณกำลังใช้ protoc
ที่ทันสมัย (ดูคำแนะนำการติดตั้งสำหรับแพลตฟอร์มของคุณเช่น protoc
v 3.0.0
ไม่รองรับ _opt
Flag
สิ่งนี้จะสร้างไฟล์ต้นฉบับ *.ts
สำหรับประเภท *.proto
ที่กำหนด
หากคุณต้องการจัดแพ็คเกจไฟล์ต้นฉบับเหล่านี้ลงในแพ็คเกจ NPM เพื่อแจกจ่ายให้กับลูกค้าเพียงเรียกใช้ tsc
บนไฟล์เหล่านั้นเพื่อสร้างไฟล์ .js
/ .d.ts
และปรับใช้เอาต์พุตเป็นแพ็คเกจ NPM ปกติ
หากคุณใช้ BUF strategy: all
ในไฟล์ buf.gen.yaml
(เอกสาร) ของคุณ
เวอร์ชัน: v1plugins: -ชื่อ: tsout: ../gen/tsstrategy: allpath: ../node_modules/ts-proto/protoc-gen-ts_proto
เพื่อป้องกัน buf push
จากการอ่านไฟล์ .proto
ที่ไม่เกี่ยวข้องกำหนดค่า buf.yaml
เช่น So:
สร้าง: ยกเว้น: [node_modules]
นอกจากนี้คุณยังสามารถใช้ปลั๊กอินอย่างเป็นทางการที่เผยแพร่ไปยัง BUF Registry
เวอร์ชัน: v1plugins: -ปลั๊กอิน: buf.build/community/stephenh-ts-protoout: ../gen/tsopt: - OutputServices = ... - USEEXACTTYPES = ...
หากคุณใช้การตั้งค่า TS ที่ทันสมัยกับ esModuleInterop
หรือทำงานในสภาพแวดล้อม ESM คุณจะต้องผ่าน ts_proto_opt
s ของ:
esModuleInterop=true
ถ้าใช้ esModuleInterop
ใน tsconfig.json
ของคุณและ
importSuffix=.js
หากดำเนินการรหัส TS-PROTO ที่สร้างขึ้นในสภาพแวดล้อม ESM
ในแง่ของรหัสที่ ts-proto
สร้างเป้าหมายทั่วไปคือ:
ประเภท Idiomatic Typescript/ES6
ts-proto
เป็นช่วงพักที่สะอาดจากรหัสของ Google/Java-esque JS protoc
ตัวหรือ "Make .d.ts
ไฟล์ความคิดเห็น *.js
" ของ protobufjs
(ในทางเทคนิค protobufjs/minimal
ใช้สำหรับการอ่าน/การเขียนไบต์จริง ๆ )
เอาต์พุต Typeprig
อินเทอร์เฟซผ่านคลาส
มากที่สุดประเภทหนึ่งเป็นเพียงอินเทอร์เฟซเพื่อให้คุณสามารถทำงานกับข้อความเช่นเดียวกับโครงสร้างแฮช/ข้อมูลปกติ
รองรับ codegen *.proto
.proto
*.ts
โปรดทราบว่า TS-PROTO ไม่ใช่กรอบ RPC นอกกรอบ แทนที่จะเป็นมีดสวิส-อาร์เฟอร์มากกว่า (ตามที่เห็นด้วยตัวเลือกการกำหนดค่ามากมาย) ซึ่งช่วยให้คุณสร้าง เฟรม เวิร์ก RPC ที่คุณต้องการได้ (เช่นที่รวมเข้ากับระบบนิเวศของ บริษัท ของคุณ , Protobuf RPC ยังคงเป็นระบบนิเวศที่ค่อนข้างกระจัดกระจาย)
หากคุณต้องการกรอบ RPC นอกกรอบที่สร้างขึ้นบน TS-Proto มีตัวอย่างบางส่วน:
nice-grpc
StarPC
(หมายเหตุสำหรับผู้มีส่วนร่วมที่มีศักยภาพหากคุณพัฒนาเฟรมเวิร์ก/มินิเฟรมเวิร์กอื่น ๆ หรือแม้แต่บล็อกโพสต์/บทเรียนเกี่ยวกับการใช้ ts-proto
เรายินดีที่จะเชื่อมโยงกับพวกเขา)
นอกจากนี้เรายังไม่สนับสนุนลูกค้าสำหรับ google.api.http
-based Google Cloud APIs โปรดดู #948 หากคุณต้องการส่ง PR
ประเภทที่สร้างขึ้นคือ "เพียงข้อมูล" เช่น:
อินเทอร์เฟซส่งออกอย่างง่าย { ชื่อ: สตริง; อายุ: จำนวน; CreateDat: วันที่ | ไม่ได้กำหนด; เด็ก: เด็ก | ไม่ได้กำหนด; รัฐ: stateenum; หลาน: เด็ก []; เหรียญ: หมายเลข [];}
พร้อมกับวิธี encode
/ decode
โรงงาน:
ส่งออก const simple = { สร้าง (baseObject?: deeppartial <Simple>): ง่าย {... }, เข้ารหัส (ข้อความ: ง่ายนักเขียน: writer = writer.create ()): นักเขียน {... }, DECODE (Reader: Reader, Length?: Number): Simple {... }, fromjson (วัตถุ: any): ง่าย {... }, FromPartial (วัตถุ: deeppartial <Simple>): ง่าย {... }, tojson (ข้อความ: ง่าย): ไม่ทราบ {... },};
สิ่งนี้ช่วยให้การใช้งาน TS/JS สำนวนเช่น:
const bytes = simple.encode ({ชื่อ: ... , อายุ: ... , ... }). เสร็จสิ้น (); const simple = simple.decode (reader.create (ไบต์)); const {ชื่อ, อายุ } = ง่าย;
ซึ่งสามารถลดการรวมเข้าด้วยกันได้อย่างมากเมื่อแปลงเป็น/จากเลเยอร์อื่น ๆ โดยไม่ต้องสร้างชั้นเรียนและเรียกผู้ที่ถูกต้อง/ตัวตั้งค่าที่เหมาะสม
ความพยายามของคนจนที่ "โปรดให้เรากลับประเภทตัวเลือก"
ประเภท wrapper protobuf canonical เช่น google.protobuf.StringValue
ถูกแมปเป็นค่าเสริมเช่น string | undefined
ซึ่งหมายความว่าสำหรับดั้งเดิมเราสามารถแกล้งทำเป็นระบบประเภท protobuf มีประเภทเสริม
( อัปเดต : TS-PROTO ตอนนี้ยังรองรับคำหลัก optional
ProTO3 ด้วย)
การประทับเวลาถูกแมปเป็น Date
(กำหนดค่าได้ด้วยพารามิเตอร์ useDate
)
fromJSON
/ toJSON
ใช้รูปแบบการเข้ารหัส JSON Canonical Canonical (เช่นการประทับเวลาเป็นสตริง ISO) ซึ่งแตกต่างจาก protobufjs
ObjectIds สามารถแมปเป็น mongodb.ObjectId
(กำหนดค่าได้ด้วยพารามิเตอร์ useMongoObjectId
))
(หมายเหตุ: ปัจจุบันได้รับการสนับสนุนโดยไคลเอนต์ TWIRP เท่านั้น)
หากคุณใช้ลูกค้าของ TS-Proto เพื่อเรียกใช้บริการไมโครแบ็กเอนด์คล้ายกับปัญหา N+1 ในแอปพลิเคชัน SQL มันเป็นเรื่องง่ายสำหรับไคลเอนต์บริการขนาดเล็กไป (เมื่อให้บริการคำขอแต่ละรายการ) โดยไม่ตั้งใจ "Get Book 1", "Get Book 2", "Get Book 3" ซึ่งควรจะเป็นชุดเดียว "Get Books [1, 2, 3]" (สมมติว่าแบ็กเอนด์รองรับวิธี RPC ที่มุ่งเน้นแบทช์)
TS-PROTO สามารถช่วยได้ในเรื่องนี้และโดยอัตโนมัติแบทช์ "Get Book" ของคุณเป็นหลักเรียกว่าการโทร "รับหนังสือ" แบทช์ "
เพื่อให้ TS-Proto ทำสิ่งนี้คุณต้องใช้วิธีการ RPC ของบริการของคุณด้วยการประชุมแบตช์ของ:
ชื่อวิธีการของ Batch<OperationName>
ประเภทอินพุต Batch<OperationName>
มีฟิลด์ซ้ำครั้งเดียว (เช่น repeated string ids = 1
)
Batch<OperationName>
ประเภทเอาต์พุตมีทั้ง::
ฟิลด์ซ้ำครั้งเดียว (เช่น repeated Foo foos = 1
) โดยที่ลำดับเอาต์พุตเหมือนกับคำสั่ง ids
อินพุต หรือ
แผนที่ของอินพุตไปยังเอาต์พุต (เช่น map<string, Entity> entities = 1;
)
เมื่อ TS-PROTO รับรู้วิธีการของรูปแบบนี้มันจะสร้างเวอร์ชัน "non-batch" ของ <OperationName>
สำหรับไคลเอนต์โดยอัตโนมัติเช่น client.Get<OperationName>
ซึ่งใช้ ID เดียวและส่งคืนผลลัพธ์เดียว
สิ่งนี้ให้รหัสลูกค้าด้วยภาพลวงตาที่สามารถทำให้แต่ละคน Get<OperationName>
การโทร (ซึ่งโดยทั่วไปดีกว่า/ง่ายกว่าเมื่อใช้ตรรกะทางธุรกิจ Batch<OperationName>
ลูกค้า) แต่การใช้งานจริงที่ TS-Proto ให้ โทรไปยังบริการแบ็กเอนด์
คุณต้องเปิดใช้งานพารามิเตอร์ useContext=true
BUILD-TIME ซึ่งให้พารามิเตอร์ ctx
แบบ go-style ทั้งหมดด้วยวิธี getDataLoaders
ที่ให้แคช TS-Proto/Resolve Dataloaders ตามคำขอ พฤติกรรมการตรวจจับ/การล้าง
ดูไฟล์ batching.proto
และการทดสอบที่เกี่ยวข้องสำหรับตัวอย่าง/รายละเอียดเพิ่มเติม
แต่เอฟเฟกต์สุทธิคือ TS-Proto สามารถให้การป้องกัน N+1-style-orm แบบ SQL- / ORM สำหรับการโทรของลูกค้าซึ่งอาจมีความสำคัญโดยเฉพาะอย่างยิ่งในการใช้งานที่มีปริมาณสูง / ขนานกันเช่นเกตเวย์ Front-Front-End .
ts-proto
เป็นปลั๊กอิน protoc
ดังนั้นคุณจึงเรียกใช้งานโดย (ไม่ว่าจะในโครงการโดยตรงหรือมีแนวโน้มมากขึ้นในท่อสคีมาโมโนรีปโปของคุณเช่น Ibotta หรือคือ):
เพิ่ม ts-proto
ลงใน package.json
ของคุณ json
เรียกใช้ npm install
เพื่อดาวน์โหลด
เรียกใช้ protoc
ด้วยพารามิเตอร์ plugin
เช่น:
protoc-plugin = node_modules/ts-proto/protoc-gen-ts_proto ./batching.proto -i
ts-proto
ยังสามารถเรียกใช้กับ Gradle โดยใช้ Protobuf-Gradle-Plugin:
protobuf { ปลั๊กอิน {// `ts` สามารถถูกแทนที่ด้วยชื่อปลั๊กอินที่ไม่ได้ใช้เช่น` tsproto`ts { path = 'path/to/plugin'} } // ส่วนนี้จำเป็นก็ต่อเมื่อคุณมี Plugin OptionsGeneratePrototasks { ทั้งหมด (). แต่ละ {task -> task.plugins {// ต้องจับคู่ปลั๊กอิน ID ประกาศ abovets { ตัวเลือก 'foo = bar'} - - - -
รหัสที่สร้างขึ้นจะถูกวางไว้ในไดเรกทอรี gradle build
ด้วย --ts_proto_opt=globalThisPolyfill=true
, TS-Proto จะรวม polyfill สำหรับ Global This
ค่าเริ่มต้นเป็น false
คือเราถือว่า globalThis
มันพร้อมใช้งาน
ด้วย --ts_proto_opt=context=true
บริการจะมีพารามิเตอร์ ctx
แบบ go-style ซึ่งมีประโยชน์สำหรับการติดตาม/การบันทึก/ฯลฯ หากคุณไม่ได้ใช้ async_hooks
API ของ Node เนื่องจากเหตุผลด้านประสิทธิภาพ
ด้วย --ts_proto_opt=forceLong=long
หมายเลข 64 บิตทั้งหมดจะถูกแยกวิเคราะห์เป็นอินสแตนซ์ของ Long
(ใช้ห้องสมุดยาว)
ด้วย --ts_proto_opt=forceLong=string
หมายเลข 64 บิตทั้งหมดจะถูกส่งออกเป็นสตริง
ด้วย --ts_proto_opt=forceLong=bigint
ตัวเลข 64 บิตทั้งหมดจะถูกส่งออกเป็น BigInt
s ตัวเลือกนี้ยังคงใช้ไลบรารี long
เพื่อเข้ารหัส/ถอดรหัสภายในภายใน protobuf.js
แต่จากนั้นแปลงเป็น/จาก BigInt
s ในรหัสที่สร้างขึ้นด้วย TS-proto
พฤติกรรมเริ่มต้นคือ forceLong=number
ซึ่งจะยังคงใช้ไลบรารี long
เพื่อเข้ารหัส/ถอดรหัสค่าบนสาย (ดังนั้นคุณจะยังคงเห็น util.Long = Long
ในเอาต์พุตของคุณ) แต่จะแปลงค่า long
เป็น number
โดยอัตโนมัติสำหรับคุณ โปรดทราบว่าข้อผิดพลาดรันไทม์จะถูกโยนลงหากในขณะที่ทำการแปลงนี้ค่า 64 บิตนั้นใหญ่กว่าสามารถเก็บไว้ได้อย่างถูกต้องเป็น number
ด้วย --ts_proto_opt=useJsTypeOverride
ตัวเลข 64 บิตจะถูกส่งออกเป็น fieldoption.jstype ที่ระบุไว้ในฟิลด์ สิ่งนี้จะมีความสำคัญกว่าตัวเลือก 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
จะเปลี่ยนประเภทของ bytes
จาก Uint8Array
เป็น Buffer
เพื่อการรวมเข้ากับระบบนิเวศของโหนดได้ง่ายขึ้นซึ่งโดยทั่วไปใช้ Buffer
ขณะนี้ browser
ไม่มีพฤติกรรมเฉพาะใด ๆ นอกเหนือจากการเป็น "ไม่ใช่ node
" มันอาจจะเร็ว ๆ นี้/ในบางจุด
ด้วย --ts_proto_opt=useOptionals=messages
(สำหรับฟิลด์ข้อความ) หรือ --ts_proto_opt=useOptionals=all
(สำหรับฟิลด์ข้อความและสเกลาร์) ฟิลด์จะถูกประกาศว่าเป็นคีย์เสริมเช่น field?: Message
แทน field: Message | undefined
ts-proto ค่าเริ่มต้นเป็น useOptionals=none
เพราะมัน:
สำหรับการป้องกันการพิมพ์ผิดฟิลด์เสริมทำให้ง่ายสำหรับฟิลด์พิเศษที่จะส่งไปยังข้อความ (จนกว่าเราจะได้รับประเภทที่แน่นอน) เช่น:
อินเทอร์เฟซ somemessage { FirstName: String; LastName: String;} // ประกาศด้วย typoconst data = {firstName: "a", lastTypo: "b"}; // ด้วย useoptionals = ไม่มีสิ่งนี้ไม่สามารถรวบรวมได้อย่างถูกต้อง; ถ้า `LastName` เป็นทางเลือกมันจะไม่เป็นข้อความ: somemessage = {... data};
สำหรับ API ที่สอดคล้องกันถ้า SomeMessage.lastName
เป็น lastName?
จากนั้นผู้อ่านจะต้องตรวจสอบเงื่อนไขที่ว่างเปล่า สอง เงื่อนไข: a) lastName
undefined
(b/c มันถูกสร้างขึ้นในหน่วยความจำและ unset ซ้าย) หรือ b) เป็น lastName
สตริงว่าง (b/c เราอ่าน SomeMessage
ออกจากลวดและต่อ ข้อมูลจำเพาะ Proto3 เริ่มต้น lastName
เป็นสตริงที่ว่างเปล่า)?
เพื่อให้มั่นใจว่าการเริ่มต้นที่เหมาะสมหากมีการเพิ่ม SomeMessage.middleInitial
ในภายหลัง middleinitial แต่มันถูกทำเครื่องหมายว่าเป็น middleInitial?
คุณอาจมีไซต์โทรหลายแห่งในรหัสการผลิตที่ ควร ผ่าน middleInitial
เพื่อสร้าง SomeMessage
ที่ถูกต้อง แต่ไม่ใช่
ดังนั้นระหว่างการป้องกันการพิมพ์ผิดความไม่สอดคล้องกันของผู้อ่านและการเริ่มต้นที่เหมาะสม TS-PROTO แนะนำให้ใช้ useOptionals=none
เป็นตัวเลือก "ปลอดภัยที่สุด"
ทั้งหมดที่กล่าวมาวิธีการนี้ต้องการนักเขียน/ผู้สร้างในการตั้งค่าทุกฟิลด์ (แม้ว่า fromPartial
และ create
มีความหมายเพื่อแก้ไขปัญหานี้) ดังนั้นหากคุณยังต้องการมีปุ่มเสริมคุณสามารถตั้ง useOptionals=messages
หรือ useOptionals=all
(ดูปัญหานี้และปัญหานี้สำหรับการอภิปรายเกี่ยวกับ useOptional
)
ป้องกันการพิมพ์ผิดเมื่อเริ่มต้นข้อความและ
ให้ API ที่สอดคล้องกันมากที่สุดแก่ผู้อ่าน
มั่นใจได้ว่าข้อความการผลิตจะเริ่มต้นอย่างเหมาะสมกับทุกฟิลด์
ด้วย --ts_proto_opt=exportCommonSymbols=false
ประเภทยูทิลิตี้เช่น DeepPartial
และ protobufPackage
จะไม่ export
d
สิ่งนี้ควรทำให้เป็นไปได้ที่จะใช้การสร้างการนำเข้าบาร์เรลของเอาต์พุตที่สร้างขึ้นเช่น import * from ./foo
และ import * from ./bar
bar
โปรดทราบว่าหากคุณมีชื่อข้อความเดียวกันที่ใช้ในไฟล์ *.proto
หลายไฟล์คุณจะยังคงได้รับความขัดแย้งในการนำเข้า
ด้วย --ts_proto_opt=oneof=unions
oneof
ฟิลด์จะถูกสร้างขึ้นเป็น adts
ดูส่วน "Oneof Handling"
ด้วย --ts_proto_opt=unrecognizedEnumName=<NAME>
enums จะมีคีย์ <NAME>
ที่มีค่าของตัวเลือก unrecognizedEnumValue
ค่าเริ่มต้นเป็น UNRECOGNIZED
ด้วย --ts_proto_opt=unrecognizedEnumValue=<NUMBER>
enums จะมีคีย์ที่จัดทำโดยตัวเลือก unrecognizedEnumName
โดยมีค่า <NUMBER>
ค่าเริ่มต้นถึง -1
ด้วย --ts_proto_opt=unrecognizedEnum=false
จะไม่มีคีย์ enum ที่ไม่รู้จักและค่าตามที่กำหนดโดยตัวเลือก unrecognizedEnumName
และตัวเลือก unrecognizedEnumValue
ด้วย --ts_proto_opt=removeEnumPrefix=true
จะมีชื่อ enum ที่ถูกลบออกจากสมาชิก
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 ของสตริง (เครื่องหมายจุลภาคถูกสงวนไว้เป็นคั่นธง) เช่น --ts_proto_opt=snakeToCamel=keys_json
ซึ่งรวม json
keys
เคสอูฐ
สตริงที่ว่างเปล่าเช่น snakeToCamel=
จะเก็บคีย์ข้อความทั้งสองและปุ่ม JSON
เป็นเคสงู (มันเหมือนกับ snakeToCamel=false
)
โปรดทราบว่าในการใช้แอตทริบิวต์ json_name
คุณจะต้องใช้ json
พฤติกรรมเริ่มต้นคือ keys_json
, IE ทั้งสองจะเป็น cased อูฐและ json_name
จะถูกใช้หากตั้งค่า
ด้วย --ts_proto_opt=outputEncodeMethods=false
, Message.encode
และ Message.decode
วิธีการสำหรับการทำงานกับข้อมูล protobuf-encoded/binary จะไม่ถูกส่งออก
สิ่งนี้มีประโยชน์หากคุณต้องการ "ประเภทเท่านั้น"
ด้วย --ts_proto_opt=outputJsonMethods=false
, Message.fromJSON
และ Message.toJSON
วิธีการสำหรับการทำงานกับข้อมูลรหัส JSON จะไม่ถูกส่งออก
สิ่งนี้ยังมีประโยชน์หากคุณต้องการ "ประเภทเท่านั้น"
ด้วย --ts_proto_opt=outputJsonMethods=to-only
และ --ts_proto_opt=outputJsonMethods=from-only
คุณจะสามารถส่งออกเพียงหนึ่งเดียวระหว่าง Message.toJSON
และ Message.fromJSON
สิ่งนี้มีประโยชน์หากคุณใช้ TS-PROTO เพียงเพื่อ encode
หรือ decode
และไม่ใช่สำหรับทั้งคู่
ด้วย --ts_proto_opt=outputPartialMethods=false
, Message.fromPartial
และ Message.create
methods สำหรับการยอมรับวัตถุ/ตัวอักษรวัตถุที่มีรูปแบบบางส่วนจะไม่ถูกส่งออก
ด้วย --ts_proto_opt=stringEnums=true
ประเภท enum ที่สร้างขึ้นจะเป็นสตริงแทนที่จะเป็น int-based
สิ่งนี้มีประโยชน์หากคุณต้องการ "ประเภทเท่านั้น" และใช้เกตเวย์ REST GRPC ที่กำหนดค่าให้เป็นอนุกรมเป็นสตริง
(ต้องการ outputEncodeMethods=false
)
ด้วย --ts_proto_opt=outputClientImpl=false
, การใช้งานไคลเอนต์, เช่น FooServiceClientImpl
ที่ใช้ฝั่งไคลเอ็นต์ (ใน TWIRP ดูตัวเลือกถัดไปสำหรับอินเตอร์เฟส grpc-web
) จะไม่ถูกส่งออก
ด้วย --ts_proto_opt=outputClientImpl=grpc-web
, การใช้งานไคลเอนต์, เช่น FooServiceClientImpl
จะใช้ @ @ @ไม่น่าจะเป็นไปได้-ENG/GRPC-WEB ไลบรารีที่รันไทม์เพื่อส่งข้อความ GRPC ไปยังแบ็กเอนด์ GRPC-WEB
(โปรดทราบว่าสิ่งนี้ใช้รันไทม์ GRPC-WEB เท่านั้นคุณไม่จำเป็นต้องใช้รหัสใด ๆ ที่สร้างขึ้นเช่นเอาต์พุต TS-Proto แทนที่เอาต์พุต ts-protoc-gen
ของพวกเขา)
คุณจะต้องเพิ่ม @improbable-eng/grpc-web
และการขนส่งไปยัง package.json
โครงการของคุณ json; ดูไดเรกทอรี integration/grpc-web
สำหรับตัวอย่างการทำงาน ดู #504 สำหรับการรวมเข้ากับ GRPC-WEB-DEVTOOLS
ด้วย --ts_proto_opt=returnObservable=true
วิธีการส่งคืนวิธีการบริการจะ Observable<T>
แทนที่จะเป็น Promise<T>
ด้วย --ts_proto_opt=addGrpcMetadata=true
อาร์กิวเมนต์สุดท้ายของวิธีการบริการจะยอมรับประเภท Metadata
GRPC ซึ่งมีข้อมูลเพิ่มเติมพร้อมการโทร (เช่นโทเค็น/ฯลฯ )
(ต้องการ nestJs=true
.)
ด้วย --ts_proto_opt=addNestjsRestParameter=true
อาร์กิวเมนต์สุดท้ายของวิธีการบริการจะเป็นพารามิเตอร์ REST ที่มีประเภทใด ๆ วิธีนี้คุณสามารถใช้งานตกแต่งที่กำหนดเองที่ปกติคุณสามารถใช้ใน NestJs
(ต้องการ nestJs=true
.)
ด้วย --ts_proto_opt=nestJs=true
ค่าเริ่มต้นจะเปลี่ยนไปเพื่อสร้าง Nestjs protobuf ประเภทที่เป็นมิตรและอินเทอร์เฟซบริการที่สามารถใช้ในทั้งฝั่งไคลเอ็นต์และฝั่งเซิร์ฟเวอร์ของการใช้งาน NestJS protobuf ดู NestJS ReadMe สำหรับข้อมูลเพิ่มเติมและตัวอย่างการใช้งาน
outputEncodeMethods
, outputJsonMethods
และ outputClientImpl
ทั้งหมดจะเป็นเท็จ, lowerCaseServiceMethods
จะเป็นจริงและจะถูก outputServices
โปรดทราบว่า addGrpcMetadata
, addNestjsRestParameter
และ returnObservable
จะยังคงเป็นเท็จ
ด้วย --ts_proto_opt=useDate=false
, ฟิลด์ประเภท google.protobuf.Timestamp
จะไม่ถูกแมปเพื่อพิมพ์ Date
ในประเภทที่สร้างขึ้น ดู Timestamp สำหรับรายละเอียดเพิ่มเติม
ด้วย --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=static-only
เพื่อละเว้นจากการประกาศ interface
หรือ --ts_proto_opt=outputTypeAnnotations=optional
เพื่อให้เป็นคุณสมบัติเสริมบนคำนิยาม 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 จะส่งออกคำจำกัดความบริการทั่วไป คำจำกัดความเหล่านี้มี descriptors สำหรับแต่ละวิธีที่มีลิงก์ไปยังการร้องขอและประเภทการตอบกลับซึ่งช่วยให้สามารถสร้างเซิร์ฟเวอร์และไคลเอ็นต์ stubs ที่รันไทม์และยังสร้างประเภทที่แข็งแกร่งสำหรับพวกเขาในเวลาคอมไพล์ ตัวอย่างของไลบรารีที่ใช้วิธีนี้คือ NICE-GRPC
ด้วย --ts_proto_opt=outputServices=nice-grpc
, TS-PROTO จะเอาต์พุตเซิร์ฟเวอร์และไคลเอ็นต์สตับสำหรับ NICE-GRPC สิ่งนี้ควรใช้ร่วมกับคำจำกัดความทั่วไปเช่นคุณควรระบุสองตัวเลือก: 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 จะเพิ่มนิยามฟังก์ชันลงในคำจำกัดความอินเตอร์เฟส RPC ด้วยลายเซ็น: beforeRequest(service: string, message: string, request: <RequestType>)
นอกจากนี้ยังจะตั้ง outputServices=default
โดยอัตโนมัติ วิธีการของบริการแต่ละวิธีจะเรียกว่า beforeRequest
ก่อนที่จะดำเนินการตามคำขอ
ด้วย --ts_proto_opt=rpcAfterResponse=true
, ts-proto จะเพิ่มนิยามฟังก์ชั่นลงในคำจำกัดความอินเตอร์เฟส RPC ด้วยลายเซ็น: afterResponse(service: string, message: string, response: <ResponseType>)
นอกจากนี้ยังจะตั้ง outputServices=default
โดยอัตโนมัติ วิธีการของบริการแต่ละวิธีจะเรียก afterResponse
ก่อนที่จะส่งคืนการตอบกลับ
ด้วย --ts_proto_opt=rpcErrorHandler=true
, ts-proto จะเพิ่มนิยามฟังก์ชันลงในคำจำกัดความอินเตอร์เฟส RPC ด้วยลายเซ็น: handleError(service: string, message: string, error: Error)
นอกจากนี้ยังจะตั้ง outputServices=default
โดยอัตโนมัติ
ด้วย --ts_proto_opt=useAbortSignal=true
บริการที่สร้างขึ้นจะยอมรับ AbortSignal
เพื่อยกเลิกการโทร RPC
ด้วย --ts_proto_opt=useAsyncIterable=true
บริการที่สร้างขึ้นจะใช้ AsyncIterable
แทน Observable
ด้วย --ts_proto_opt=emitImportedFiles=false
, ts-proto จะไม่ปล่อยไฟล์ google/protobuf/*
เว้นแต่คุณจะเพิ่มไฟล์อย่างชัดเจนใน protoc
เช่น protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto my_message.proto google/protobuf/duration.proto
นี้ protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto my_message.proto google/protobuf/duration.proto
ด้วย --ts_proto_opt=fileSuffix=<SUFFIX>
, TS-Proto จะปล่อยไฟล์ที่สร้างขึ้นโดยใช้คำต่อท้ายที่ระบุ ไฟล์ helloworld.proto
ที่มี fileSuffix=.pb
จะถูกสร้างขึ้นเป็น helloworld.pb.ts
นี่เป็นพฤติกรรมที่พบบ่อยในปลั๊กอินโปรโตตอื่น ๆ และให้วิธีการที่จะทำให้ไฟล์ทั้งหมดที่สร้างขึ้นได้อย่างรวดเร็ว
ด้วย --ts_proto_opt=importSuffix=<SUFFIX>
, TS-PROTO จะปล่อยการนำเข้าไฟล์โดยใช้คำต่อท้ายที่ระบุ การนำเข้า helloworld.ts
ด้วย fileSuffix=.js
จะสร้าง import "helloworld.js"
ค่าเริ่มต้นคือการนำเข้าโดยไม่ต้องขยายไฟล์ รองรับโดย TypeScript 4.7.x ขึ้นไป
ด้วย --ts_proto_opt=enumsAsLiterals=true
ประเภท enum ที่สร้างขึ้นจะเป็นวัตถุ enum-ish ที่มี as const
ด้วย --ts_proto_opt=useExactTypes=false
การสร้าง fromPartial
และวิธี create
จะไม่ใช้ประเภทที่แน่นอน
พฤติกรรมเริ่มต้นคือ useExactTypes=true
ซึ่งทำให้ fromPartial
และ create
ประเภทการใช้งานที่แน่นอนสำหรับอาร์กิวเมนต์เพื่อให้ TypeScript ปฏิเสธคุณสมบัติที่ไม่รู้จัก
ด้วย --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
สิ่งนี้ช่วยให้โค้ดทำการตรวจสอบหิวเพื่อตรวจจับเมื่อมีการใช้ค่าเริ่มต้นซึ่งเนื่องจากพฤติกรรมของ Proto3 ที่ไม่ได้ใส่ค่าเริ่มต้นบนลวดมักจะมีประโยชน์สำหรับการโต้ตอบกับข้อความ ProTO2 เท่านั้น
เมื่อเปิดใช้งานค่าเริ่มต้นจะสืบทอดมาจากต้นแบบและดังนั้นรหัสสามารถใช้ Object.keys () รวมถึง ("บางฟิลด์") เพื่อตรวจจับว่า Simerfield ได้รับการถอดรหัสจริงหรือไม่
โปรดทราบว่าตามที่ระบุไว้นี่หมายถึง Object.keys จะไม่รวมฟิลด์แบบตั้งค่าโดยใช้การตั้งค่าดังนั้นหากคุณมีรหัสที่วนซ้ำผ่านคีย์ข้อความในรูปแบบทั่วไปมันจะต้องทำซ้ำข้ามคีย์ที่สืบทอดมาจากต้นแบบ
ด้วย --ts_proto_opt=useJsonName=true
, json_name
ที่กำหนดไว้ใน protofiles จะถูกใช้แทนชื่อฟิลด์ข้อความ
ด้วย --ts_proto_opt=useJsonWireFormat=true
รหัสที่สร้างขึ้นจะสะท้อนให้เห็นถึงการแสดง JSON ของข้อความ protobuf
ต้องใช้ onlyTypes=true
หมายถึง useDate=string
และ stringEnums=true
ตัวเลือกนี้คือการสร้างประเภทที่สามารถใช้โดยตรงกับ marshalling/unmarshalling protobuf message serialized เป็น JSON คุณอาจต้องการตั้ง useOptionals=all
เนื่องจากเกตเวย์ GRPC ไม่จำเป็นต้องส่งค่าเริ่มต้นสำหรับค่าสเกลาร์
ด้วย --ts_proto_opt=useNumericEnumForJson=true
ตัวแปลง JSON ( toJSON
) จะเข้ารหัสค่า enum เป็น int แทนที่จะเป็นตัวอักษรสตริง
ด้วย --ts_proto_opt=initializeFieldsAsUndefined=false
ฟิลด์เริ่มต้นที่เป็นตัวเลือกทั้งหมดจะถูกตัดออกจากอินสแตนซ์พื้นฐานที่สร้างขึ้น
ด้วย --ts_proto_opt=disableProto2Optionals=true
ฟิลด์เสริมทั้งหมดในไฟล์ Proto2 จะไม่ถูกตั้งค่าเป็นตัวเลือก โปรดทราบว่าการตั้งค่าสถานะนี้เป็นหลักสำหรับการรักษาไฟล์ Proto2 แบบดั้งเดิมของ TS-Proto เพื่อหลีกเลี่ยงการเปลี่ยนแปลงและเป็นผลให้มันไม่ได้มีวัตถุประสงค์เพื่อใช้การก้าวไปข้างหน้า
ด้วย --ts_proto_opt=disableProto2DefaultValues=true
ทั้งหมดฟิลด์ทั้งหมดในไฟล์ Proto2 ที่ระบุค่าเริ่มต้นจะไม่ใช้ค่าเริ่มต้นนั้นจริง โปรดทราบว่าการตั้งค่าสถานะนี้เป็นหลักสำหรับการรักษาไฟล์ Proto2 แบบดั้งเดิมของ TS-Proto เพื่อหลีกเลี่ยงการเปลี่ยนแปลงและเป็นผลให้มันไม่ได้มีวัตถุประสงค์เพื่อใช้การก้าวไปข้างหน้า
ด้วย --ts_proto_opt=Mgoogle/protobuf/empty.proto=./google3/protobuf/empty
('m' หมายถึง 'นำเข้าการทำ' คล้ายกับ protoc-gen-go) เส้นทางนำเข้ารหัสที่สร้างขึ้นสำหรับ ./google/protobuf/empty.ts
จะสะท้อนถึงค่าที่ถูกแทนที่:
Mfoo/bar.proto=@myorg/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...
(หนึ่ง ts_proto_opt
ต่อการแมป)
หมายเหตุ : ไฟล์โปรโตที่ตรงกับการนำเข้าที่แมป จะไม่ถูกสร้างขึ้น
ด้วย --ts_proto_opt=useMapType=true
รหัสที่สร้างขึ้นสำหรับ map<key_type, value_type>
จะกลายเป็น Map<key_type, value_type>
ที่ใช้ประเภทแผนที่ JavaScript
พฤติกรรมเริ่มต้นคือ useMapType=false
ซึ่งทำให้มันสร้างรหัสสำหรับ map<key_type, value_type
กับคู่คีย์-ค่าเช่น {[key: key_type]: value_type}
ด้วย --ts_proto_opt=useReadonlyTypes=true
ประเภทที่สร้างขึ้นจะถูกประกาศว่าเป็นแบบไม่เปลี่ยนรูปแบบโดยใช้ตัวดัดแปลง readonly
เดียวของ TypeScript
ด้วย --ts_proto_opt=useSnakeTypeName=false
จะลบปลอกงูออกจากประเภท
ตัวอย่าง protobuf
กล่องข้อความ {องค์ประกอบข้อความ {รูปภาพข้อความ {การจัดตำแหน่ง enum {left = 1; ศูนย์ = 2; ขวา = 3; - - - -
โดยค่าเริ่มต้นสิ่งนี้จะเปิดใช้งานซึ่งจะสร้างประเภทของ Box_Element_Image_Alignment
โดยการปิดการใช้งานตัวเลือกนี้ประเภทที่สร้างขึ้นจะเป็น BoxElementImageAlignment
ด้วย --ts_proto_opt=outputExtensions=true
รหัสที่สร้างขึ้นจะรวมถึงส่วนขยาย Proto2
วิธีการ Extension Excode/Decode นั้นสอดคล้องกับตัวเลือก outputEncodeMethods
และหาก unknownFields=true
วิธี setExtension
และ getExtension
จะถูกสร้างขึ้นสำหรับข้อความที่ขยายได้และสอดคล้องกับ outputEncodeMethods
(setExtension = ENCODE
ด้วย --ts_proto_opt=outputIndex=true
ไฟล์ดัชนีจะถูกสร้างขึ้นตามเนมสเปซแพ็คเกจ Proto
สิ่งนี้จะปิดการใช้งาน exportCommonSymbols
เพื่อหลีกเลี่ยงการชนกันของชื่อในสัญลักษณ์ทั่วไป
ด้วย --ts_proto_opt=emitDefaultValues=json-methods
วิธี TOJSON ที่สร้างขึ้นจะปล่อยสเกลาร์เช่น 0
และ ""
เป็นฟิลด์ JSON
ด้วย --ts_proto_opt=comments=false
ความคิดเห็นจะไม่ถูกคัดลอกจากไฟล์ proto ไปยังรหัสที่สร้างขึ้น
ด้วย --ts_proto_opt=bigIntLiteral=false
รหัสที่สร้างขึ้นจะใช้ BigInt("0")
แทน 0n
สำหรับตัวอักษร Bigint ตัวอักษร Bigint ไม่ได้รับการสนับสนุนโดย TypeScript เมื่อตัวเลือกคอมไพเลอร์ "เป้าหมาย" ตั้งค่าเป็นสิ่งที่เก่ากว่า "ES2020"
ด้วย --ts_proto_opt=useNullAsOptional=true
ค่า undefined
จะถูกแปลงเป็น null
และหากคุณใช้ป้ายกำกับ optional
ในไฟล์ .proto
ของคุณฟิลด์จะมีประเภท undefined
เช่นกัน ตัวอย่างเช่น:
ด้วย --ts_proto_opt=typePrefix=MyPrefix
, อินเตอร์เฟสที่สร้างขึ้น, enums และโรงงานจะมีคำนำหน้าของ MyPrefix
ในชื่อของพวกเขา
ด้วย --ts_proto_opt=typeSuffix=MySuffix
อินเตอร์เฟสที่สร้างขึ้น enums และโรงงานจะมีคำต่อท้ายของ MySuffix
ในชื่อของพวกเขา
ข้อความ profileInfo {int32 id = 1; สตริง bio = 2; สตริงโทรศัพท์ = 3; } แผนกข้อความ {int32 id = 1; ชื่อสตริง = 2; } ผู้ใช้ข้อความ {int32 id = 1; string username = 2;/* profileInfo จะเป็นตัวเลือกใน typeScript ประเภทจะเป็น profileInfo | NULL ไม่ได้กำหนดสิ่งนี้เป็นสิ่งจำเป็นในกรณีที่คุณไม่ต้องการให้คุณค่าใด ๆ สำหรับโปรไฟล์ */โปรไฟล์โปรไฟล์ที่เป็นตัวเลือก = 3;/* แผนกยอมรับประเภทแผนกหรือโมฆะเท่านั้นดังนั้นหมายความว่าคุณต้องส่งผ่านว่างถ้าไม่มีค่า */แผนก = 4; -
อินเทอร์เฟซที่สร้างขึ้นจะเป็น:
Export Interface ProfileInfo { ID: หมายเลข; ชีวภาพ: สตริง; โทรศัพท์: สตริง;} แผนกอินเตอร์เฟสส่งออก { ID: หมายเลข; ชื่อ: string;} ผู้ใช้อินเตอร์เฟสส่งออก { ID: หมายเลข; ชื่อผู้ใช้: สตริง; โปรไฟล์?: ProfileInfo | NULL ไม่ได้กำหนด; // ตรวจสอบอันนี้ แผนก: แผนก | โมฆะ; // ตรวจสอบอันนี้}
ด้วย --ts_proto_opt=noDefaultsForOptionals=true
ค่าดั้งเดิม undefined
จะไม่ถูกผิดนัดตามข้อมูลจำเพาะ protobuf นอกจากนี้ยังแตกต่างจากพฤติกรรมมาตรฐานเมื่อฟิลด์ถูกตั้งค่าเป็นค่าเริ่มต้นมาตรฐานมัน จะ ถูกเข้ารหัสอนุญาตให้ส่งผ่านสายและแตกต่างจากค่าที่ไม่ได้กำหนด ตัวอย่างเช่นหากข้อความไม่ได้ตั้งค่าบูลีนโดยปกติแล้วสิ่งนี้จะผิดนัดเป็น false
ซึ่งแตกต่างจากที่ไม่ได้กำหนด
ตัวเลือกนี้ช่วยให้ห้องสมุดสามารถดำเนินการในลักษณะที่เข้ากันได้กับการใช้งานสายการดูแลและใช้งานโดยสแควร์/บล็อก หมายเหตุ: ควรใช้ตัวเลือกนี้ร่วมกับรหัสไคลเอนต์/เซิร์ฟเวอร์อื่น ๆ ที่สร้างขึ้นโดยใช้ Wire หรือ TS-PROTO กับตัวเลือกนี้ที่เปิดใช้งาน
เรามีวิธีที่ยอดเยี่ยมในการทำงานร่วมกับ NestJs ts-proto
สร้าง interfaces
และ decorators
สำหรับคุณคอนโทรลเลอร์ไคลเอนต์ สำหรับข้อมูลเพิ่มเติมโปรดดู Nestjs Readme
หากคุณต้องการเรียกใช้ ts-proto
ในทุกการเปลี่ยนแปลงของไฟล์ Proto คุณจะต้องใช้เครื่องมือเช่น Chokidar-CLI และใช้เป็นสคริปต์ใน package.json
:
"Proto: สร้าง": "protoc --ts_proto_out = ./<proto_path>/<proto_name> C "NPM Run Proto: สร้าง" "
ts-proto
เป็น RPC Framework Agnostic - วิธีที่คุณส่งข้อมูลของคุณไปและกลับจากแหล่งข้อมูลของคุณขึ้นอยู่กับคุณ การใช้งานไคลเอนต์ที่สร้างขึ้นทั้งหมดคาดว่าจะมีพารามิเตอร์ rpc
ซึ่งประเภทใดที่กำหนดไว้เช่นนี้:
อินเตอร์เฟส rpc { คำขอ (บริการ: สตริง, วิธี: สตริง, ข้อมูล: uint8array): สัญญา <uint8array>;}
หากคุณทำงานกับ GRPC การใช้งานง่าย ๆ อาจมีลักษณะเช่นนี้:
const conn = new grpc.client ( "Localhost: 8765", grpc.credentials.createinsecure ()); พิมพ์ rpcimpl = (บริการ: สตริง, วิธี: สตริง, ข้อมูล: uint8array) => สัญญา <uint8array>; const sendrequest: rpcimpl = (บริการ, วิธี, ข้อมูล) => { // ตามปกติใน GRPC เส้นทางคำขอดูเหมือน // "package.names.servicename/methodname" // ดังนั้นเราจึงสร้างสตริงดังกล่าว const path = `/$ {service}/$ {method}`; ส่งคืนสัญญาใหม่ ((แก้ไข, ปฏิเสธ) => {// makeunaryRequest ส่งผลลัพธ์ (และข้อผิดพลาด) ด้วยการเรียกกลับ // แปลงเป็นสัญญา! (err) {return reject (err);} redent (res);}; ฟังก์ชั่น passthrough (อาร์กิวเมนต์: ใด ๆ ) {return rigment;} // การใช้ passther เป็น serialize และ deserialize functionsconn.makeunaryrequest , resultcallback); });}; const rpc: rpc = {คำขอ: sendrequest};
ขอชื่นชมผู้สนับสนุนของเรา:
การสนับสนุน GRPC-WEB เริ่มต้นของ NGROK ได้รับการสนับสนุนจาก TS-Proto
หากคุณต้องการการปรับแต่ง TS-PROTO หรือการสนับสนุนลำดับความสำคัญสำหรับ บริษัท ของคุณคุณสามารถ ping ฉันทางอีเมล
ส่วนนี้อธิบายถึงวิธีการมีส่วนร่วมโดยตรงกับ TS-PROTO นั่นคือไม่จำเป็นสำหรับการเรียกใช้ ts-proto
ใน protoc
หรือใช้ TypeScript ที่สร้างขึ้น
ความต้องการ
นักเทียบท่า
yarn
npm install -g yarn
การตั้งค่า
คำสั่งด้านล่างถือว่าคุณติดตั้ง Docker แล้ว หากคุณใช้ OS X ให้ติดตั้ง CoreUtils , brew install coreutils
ตรวจสอบที่เก็บสำหรับรหัสล่าสุด
เรียกใช้ yarn install
เพื่อติดตั้งการพึ่งพา
เรียกใช้ yarn build:test
เพื่อสร้างไฟล์ทดสอบ
สิ่งนี้เรียกใช้คำสั่งต่อไปนี้:
proto2ts
รัน ts-proto
ใน integration/**/*.proto
เพื่อสร้างไฟล์. .ts
proto2pbjs
- สร้างการใช้งานอ้างอิงโดยใช้ pbjs
สำหรับการทดสอบความเข้ากันได้
เรียกใช้ yarn test
เวิร์กโฟลว์
เพิ่ม/อัปเดตการทดสอบการรวมสำหรับกรณีการใช้งานของคุณ
นอกจากนี้คุณยังสามารถออกจากการทำงาน yarn watch
และมันควร "ทำสิ่งที่ถูกต้อง"
สร้าง integration/your-new-test/parameters.txt
ด้วยพารามิเตอร์ ts_proto_opt
ที่จำเป็น
สร้าง integration/your-new-test/your-new-test.proto
schema proto เพื่อทำซ้ำเคสการใช้งานของคุณ
ค้นหาการทดสอบ integration/*
ที่มีอยู่ใกล้เคียงกับกรณีการใช้งานของคุณเช่นมี parameters.txt
ที่ตรงกับพารามิเตอร์ ts_proto_opt
ที่จำเป็นในการทำซ้ำกรณีการใช้งานของคุณ
หากสร้างการทดสอบการรวมใหม่:
หลังจากการเปลี่ยนแปลงใด ๆ กับ 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/*.ts
ให้เรียกใช้ yarn proto2ts
เรียกใช้ yarn test
เพื่อตรวจสอบการเปลี่ยนแปลงของคุณผ่านการทดสอบที่มีอยู่ทั้งหมด
มอบหมายและส่ง PR
บางครั้งการตรวจสอบในรหัสที่สร้างขึ้นนั้นขมวดคิ้ว แต่งานหลักของ TS-Proto คือการสร้างรหัสโดยการเห็น codegen diffs ใน PRS มีประโยชน์
เรียกใช้ yarn format
เพื่อจัดรูปแบบไฟล์ typeScript
git add
ไฟล์ *.proto
, *.bin
และ *.ts
ทั้งหมดใน integration/your-new-test
การทดสอบในโครงการของคุณ
คุณสามารถทดสอบการเปลี่ยนแปลง TS-PROTO ในพื้นที่ของคุณในโครงการของคุณเองโดยใช้ yarn add ts-proto@./path/to/ts-proto
ตราบใดที่คุณเรียกใช้ yarn build
ด้วยตนเอง
Dockerized Protoc
ที่เก็บประกอบด้วย protoc
เวอร์ชัน Dockerized ซึ่งกำหนดค่าใน Docker-compose.yml
มันจะมีประโยชน์ในกรณีที่คุณต้องการเรียกใช้ปลั๊กอินด้วยตนเองด้วย protoc
เวอร์ชันที่รู้จัก
การใช้งาน:
# รวมนามแฝง protoc ในเปลือกของคุณ .. นามแฝง ssh# เรียกใช้โปรโตตตามปกติ ไดเรกทอรี TS-Proto มีอยู่ใน /ts-proto.protoc-plugin =/ts-proto/protoc-gen-ts_proto--ts_proto_out =./output -i =./protos ./protoc/**.proto# หรือ ใช้นามแฝง TS-Protoc ซึ่งระบุเส้นทางปลั๊กอินสำหรับคุณ
เส้นทางทั้งหมดจะต้องเป็นเส้นทางที่สัมพันธ์กัน ภายใน ไดเรกทอรีการทำงานปัจจุบันของโฮสต์ ../
ไม่อนุญาต
ภายในคอนเทนเนอร์ Docker เส้นทางที่แน่นอนไปยังรูทโครงการคือ /ts-proto
คอนเทนเนอร์ติดตั้งไดเรกทอรีการทำงานปัจจุบันใน /host
และตั้งค่าเป็นไดเรกทอรีการทำงาน
เมื่อมีการจัดหา aliases.sh
คุณสามารถใช้คำสั่ง protoc
ในโฟลเดอร์ใดก็ได้
ชื่อโมดูล TS/ES6 คือแพ็คเกจโปรโต
รองรับการเข้ารหัสที่ใช้สตริงของระยะเวลาใน fromJSON
/ toJSON
สร้าง oneof=unions-value
พฤติกรรมเริ่มต้นใน 2.0
อาจเปลี่ยนค่าเริ่มต้น forceLong
ใน 2.0 ควรเริ่มต้นเป็น forceLong=long
ทำให้ esModuleInterop=true
ค่าเริ่มต้นใน 2.0
โดยค่าเริ่มต้น TS-PROTO รุ่น oneof
ฟิลด์ "แบน" ในข้อความเช่นข้อความเช่น:
ข้อความ foo {oneof ทั้งสอง {String field_a = 1; String field_b = 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"; ค่า: สตริง};}
เนื่องจากสิ่งนี้จะบังคับใช้โดยอัตโนมัติเพียงหนึ่งใน field_a
หรือ field_b
"ถูกตั้งค่า" ในแต่ละครั้งเพราะค่าจะถูกเก็บไว้ในฟิลด์ eitherField
ที่สามารถมีค่าเดียวในแต่ละครั้ง
(โปรดทราบว่า eitherField
เป็นตัวเลือก b/c oneof
ใน protobuf หมายถึง "อย่างมากที่สุดหนึ่งฟิลด์" ถูกตั้งค่าและไม่ได้หมายความว่าหนึ่งในฟิลด์ จะต้อง ตั้งค่า)
ในการเปิดตัว 2.x ที่ไม่ได้กำหนดไว้ในปัจจุบันของ TS-Proto, oneof=unions-value
จะกลายเป็นพฤติกรรมเริ่มต้น
นอกจากนี้ยังมีตัวเลือก oneof=unions
ซึ่งสร้างสหภาพที่ชื่อฟิลด์รวมอยู่ในแต่ละตัวเลือก:
อินเทอร์เฟซ YourMessage { ทั้งสอง: {$ case: "field_a"; Field_a: String} | {$ case: "field_b"; field_b: string};}
ไม่แนะนำอีกต่อไปเนื่องจากอาจเป็นเรื่องยากที่จะเขียนโค้ดและประเภทเพื่อจัดการกับตัวเลือกหนึ่งตัวเลือกหลายตัวเลือก:
ประเภทผู้ช่วยต่อไปนี้อาจทำให้ง่ายต่อการทำงานกับประเภทที่สร้างขึ้นจาก oneof=unions
แม้ว่าโดยทั่วไปจะไม่จำเป็นถ้าคุณใช้ oneof=unions-value
:
/** แยกชื่อเคสทั้งหมดออกจากฟิลด์ Oneof */พิมพ์ oneofcases <t> = t ขยาย {$ case: อนุมานคุณขยายสตริง}? U: ไม่เคย;/** แยกสหภาพของประเภทค่าทั้งหมดจากฟิลด์หนึ่ง*/พิมพ์ oneofvalues <t> = t ขยาย {$ case: อนุมานคุณขยายสตริง; [คีย์: สตริง]: ไม่ทราบ}? t [u]: ไม่เคย;/** แยกประเภทเฉพาะของเคสหนึ่งตัวตามชื่อฟิลด์*/พิมพ์ oneofcase <t, k ขยาย oneofcases <t >> = t ขยาย { $ case: k; [คีย์: สตริง]: ไม่ทราบ;} - T : ไม่เคย;/** แยกประเภทเฉพาะของประเภทค่าจากฟิลด์ oneof*/type oneofvalue <t, k ขยาย oneofcases <t >> = t ขยาย { $ case: อนุมานคุณขยาย k; [คีย์: สตริง]: ไม่ทราบ;} - t [u] : ไม่เคย;
สำหรับการเปรียบเทียบค่าเทียบเท่าสำหรับ oneof=unions-value
:
/** แยกชื่อเคสทั้งหมดออกจากฟิลด์ Oneof */พิมพ์ oneofcases <t> = t ['$ case'];/** สกัดสหภาพของประเภทค่าทั้งหมดจากฟิลด์หนึ่งของฟิลด์*/พิมพ์ oneofvalues <t> = t ['value'];/** สารสกัด ประเภทเฉพาะของเคส OneOf ตามชื่อฟิลด์ */พิมพ์ OneOfCase <T, K ขยาย OneOfCases <T >> = T ขยาย { $ case: k; [คีย์: สตริง]: ไม่ทราบ;} - T : ไม่เคย;/** แยกประเภทเฉพาะของประเภทค่าจากฟิลด์ oneof*/type oneofvalue <t, k ขยาย oneofcases <t >> = t ขยาย { $ case: อนุมานคุณขยาย k; ค่า: ไม่ทราบ;} - t [u] : ไม่เคย;
ใน Core Protobuf (และเช่นเดียวกับ ts-proto
) ค่าที่ ไม่ได้รับการตรวจสอบ หรือเท่ากับค่าเริ่มต้นจะไม่ถูกส่งผ่านสาย
ตัวอย่างเช่นค่าเริ่มต้นของข้อความ undefined
ประเภทดั้งเดิมใช้ค่าเริ่มต้นตามธรรมชาติเช่น string
คือ ''
, number
คือ 0
ฯลฯ
Protobuf เลือก/บังคับใช้พฤติกรรมนี้เพราะมันช่วยให้เข้ากันได้ไปข้างหน้าเนื่องจากฟิลด์ดั้งเดิมจะมีค่าเสมอแม้เมื่อถูกละเว้นโดยตัวแทนที่ล้าสมัย
นี่เป็นสิ่งที่ดี แต่ก็หมายถึง ค่าเริ่มต้น และค่า Unset ไม่สามารถแยกแยะได้ในฟิลด์ ts-proto
มันเป็นเพียงแค่วิธีการทำงานของ Protobuf
หากคุณต้องการฟิลด์ดั้งเดิมที่คุณสามารถตรวจจับ Set/UNSET ให้ดูประเภท wrapper
เข้ารหัส / ถอดรหัส
ts-proto
ปฏิบัติตามกฎ Protobuf และส่งคืนค่าเริ่มต้นสำหรับฟิลด์ UNSESTS เมื่อถอดรหัสในขณะที่ละเว้นจากเอาต์พุตเมื่ออนุกรมในรูปแบบไบนารี
ไวยากรณ์ = "proto3"; ข้อความ foo {สตริงบาร์ = 1; -
Protobufbytes; // สมมติว่านี่เป็นวัตถุ foo ที่ว่างเปล่าใน protobuf binary formatfoo.decode (protobufbytes); // => {bar: ''}
foo.encode ({bar: ""}); // => {} เขียนวัตถุ foo ที่ว่างเปล่าในรูปแบบไบนารี protobuf
จาก Json / Tojson
การอ่าน JSON จะเริ่มต้นค่าเริ่มต้น เนื่องจากผู้ส่งอาจละเว้นฟิลด์ UNSET หรือตั้งค่าเป็นค่าเริ่มต้นให้ใช้ fromJSON
เพื่อทำให้อินพุตเป็นปกติ
foo.fromjson ({}); // => {bar: ''} foo.fromjson ({bar: ""}); // => {bar: ''} foo.fromjson ({bar: "baz"}); // => {bar: 'baz'}
เมื่อเขียน JSON, ts-proto
ทำให้ข้อความเป็นปกติโดยการละฟิลด์ UNSET และฟิลด์ที่ตั้งค่าเป็นค่าเริ่มต้น
foo.tojson ({}); // => {} foo.tojson ({bar: undefined}); // => {} foo.tojson ({bar: ""}); // => {} - หมายเหตุ: การละเว้นค่าเริ่มต้นตามที่คาดหวัง foo.tojson ({bar: "baz"}); // => {bar: 'baz'}
Protobuf มาพร้อมกับคำจำกัดความของข้อความที่กำหนดไว้ล่วงหน้าหลายรายการเรียกว่า "ประเภทที่รู้จักกันดี" การตีความของพวกเขาถูกกำหนดโดยข้อกำหนดของ Protobuf และคาดว่าไลบรารีจะแปลงข้อความเหล่านี้เป็นประเภทดั้งเดิมที่สอดคล้องกันในภาษาเป้าหมาย
ปัจจุบัน ts-proto
แปลงข้อความเหล่านี้เป็นประเภทดั้งเดิมที่สอดคล้องกันโดยอัตโนมัติ
google.protobuf.boolvalue ⇆ boolean
google.protobuf.bytesvalue ⇆ Uint8Array
google.protobuf.doublevalue ⇆ number
google.protobuf.fieldmask ⇆ 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 }
ประเภท wrapper เป็นข้อความที่มีฟิลด์ดั้งเดิมเดียวและสามารถนำเข้าในไฟล์ .proto
ที่มี import "google/protobuf/wrappers.proto"
เนื่องจากสิ่งเหล่านี้เป็น ข้อความ ค่าเริ่มต้นของพวกเขาจึง undefined
ทำให้คุณสามารถแยกความแตกต่างของ UNSET ดั้งเดิมจากค่าเริ่มต้นของพวกเขาเมื่อใช้ประเภท wrapper ts-proto
สร้างฟิลด์เหล่านี้เป็น <primitive> | undefined
ตัวอย่างเช่น:
// protobufsyntax = "proto3"; นำเข้า "Google/protobuf/wrappers.proto"; ข้อความ ExampleMessage {google.protobuf.stringValue ชื่อ = 1; -
// typeScriptInterface ExampleMessage { ชื่อ: สตริง | ไม่ได้กำหนด;}
เมื่อเข้ารหัสข้อความค่าดั้งเดิมจะถูกแปลงกลับเป็นประเภท wrapper ที่สอดคล้องกัน:
ExampleMessage.encode ({ชื่อ: "foo"}); // => {ชื่อ: {value: 'foo'}} ในไบนารี
เมื่อเรียก TOJSON ค่าจะไม่ถูกแปลงเนื่องจากประเภท wrapper เป็นสำนวนใน JSON
ExampleMessage.tojson ({ชื่อ: "foo"}); // => {ชื่อ: 'foo'}
ภาษาและประเภทของ Protobuf ไม่เพียงพอที่จะแสดงค่า JSON ที่เป็นไปได้ทั้งหมดเนื่องจาก JSON อาจมีค่าที่ไม่ทราบประเภทล่วงหน้า ด้วยเหตุนี้ Protobuf จึงเสนอประเภทเพิ่มเติมหลายประเภทเพื่อแสดงถึงค่า JSON โดยพลการ
สิ่งเหล่านี้เรียกว่าประเภทโครงสร้างและสามารถนำเข้าในไฟล์ .proto
ที่มี import "google/protobuf/struct.proto"
google.protobuf.value ⇆ any
นี่เป็นประเภททั่วไปมากที่สุดและสามารถแสดงค่า JSON ใด ๆ (เช่น number | string | boolean | null | array | object
)
google.protobuf.listvalue ⇆ any[]
เพื่อเป็นตัวแทนของอาร์เรย์ JSON
google.protobuf.struct ⇆ { [key: string]: any }
เพื่อเป็นตัวแทนของวัตถุ JSON
ts-proto
แปลงกลับไปกลับมาระหว่างประเภทโครงสร้างเหล่านี้และประเภท JSON ที่สอดคล้องกันโดยอัตโนมัติ
ตัวอย่าง:
// protobufsyntax = "proto3"; นำเข้า "Google/protobuf/struct.proto"; ข้อความ ExampleMessage {google.protobuf.Value ทุกอย่าง = 1; -
// typeScriptInterface ExampleMessage { อะไรก็ได้: ใด ๆ | ไม่ได้กำหนด;}
การเข้ารหัสค่า JSON ที่ฝังอยู่ในข้อความแปลงเป็นประเภทโครงสร้าง:
ExampleMessage.encode ({อะไรก็ได้: {ชื่อ: "hello"}});/* เอาต์พุตโครงสร้างต่อไปนี้เข้ารหัสในรูปแบบไบนารี protobuf: {อะไรก็ได้: value {structValue = struct {fields = [mapentry {key = "ชื่อ", value = value {stringValue = "hello"}]}}}}*/exampleMessage.encode ({อะไร: true});/* เอาต์พุตโครงสร้างต่อไปนี้เข้ารหัสในรูปแบบไบนารี protobuf: {อะไรก็ได้: ค่า {boolvalue = true}}}}}}}}} */
การเป็นตัวแทนของ google.protobuf.Timestamp
สามารถกำหนดค่าได้โดย Flag useDate
Flag useJsonTimestamp
ควบคุมความแม่นยำเมื่อ useDate
เป็น false
Protobuf ประเภทที่รู้จักกันดี | ค่าเริ่มต้น/ useDate=true | useDate=false | useDate=string | useDate=string-nano |
---|---|---|---|---|
google.protobuf.Timestamp | Date | { seconds: number, nanos: number } | string | string |
เมื่อใช้ useDate=false
และ useJsonTimestamp=raw
timestamp แสดงเป็น { seconds: number, nanos: number }
แต่มีความแม่นยำของนาโนวินาที
เมื่อใช้ useDate=string-nano
timestamp แสดงเป็นสตริง ISO ที่มีความแม่นยำนาโนวินาที 1970-01-01T14:27:59.987654321Z
และอาศัยไลบรารีนาโนวันที่สำหรับการแปลง คุณจะต้องติดตั้งในโครงการของคุณ
ตัวเลขนั้นเป็นค่าเริ่มต้นที่ถือว่าเป็น number
จาวาสคริปต์ธรรมดา
นี่เป็นสิ่งที่ดีสำหรับประเภท protobuf เช่น int32
และ float
แต่ประเภท 64 บิตเช่น int64
ไม่สามารถแสดงได้ 100% โดยประเภท number
ของ JavaScript เนื่องจาก int64
สามารถมีค่าที่ใหญ่กว่า/เล็กกว่า number
การกำหนดค่าเริ่มต้นของ TS-Proto (ซึ่งเป็น forceLong=number
) คือการใช้ number
สำหรับฟิลด์ 64 บิตแล้วโยนข้อผิดพลาดหากค่า (ที่รันไทม์) มีขนาดใหญ่กว่า Number.MAX_SAFE_INTEGER
หากคุณคาดว่าจะใช้ค่า 64 บิต / สูงกว่า MAX_SAFE_INTEGER
คุณสามารถใช้ตัวเลือก TS-Proto forceLong
ซึ่งใช้แพ็คเกจ NPM ยาวเพื่อรองรับช่วงทั้งหมดของค่า 64 บิต
ประเภทหมายเลข protobuf แผนที่ไปยังประเภท JavaScript ตามตัวเลือกการกำหนดค่า forceLong
:
ประเภทหมายเลข protobuf | ค่าเริ่มต้น/ forceLong=number | forceLong=long | forceLong=string |
---|---|---|---|
สองเท่า | ตัวเลข | ตัวเลข | ตัวเลข |
ลอย | ตัวเลข | ตัวเลข | ตัวเลข |
INT32 | ตัวเลข | ตัวเลข | ตัวเลข |
INT64 | ตัวเลข* | ยาว | สาย |
uint32 | ตัวเลข | ตัวเลข | ตัวเลข |
uint64 | ตัวเลข* | ไม่ได้ลงนาม | สาย |
sint32 | ตัวเลข | ตัวเลข | ตัวเลข |
SINT64 | ตัวเลข* | ยาว | สาย |
แก้ไข 32 | ตัวเลข | ตัวเลข | ตัวเลข |
แก้ไข 64 | ตัวเลข* | ไม่ได้ลงนาม | สาย |
sfixed32 | ตัวเลข | ตัวเลข | ตัวเลข |
sfixed64 | ตัวเลข* | ยาว | สาย |
โดยที่ (*) ระบุว่าพวกเขาอาจโยนข้อผิดพลาดที่รันไทม์
Primitives ที่จำเป็น: ใช้ AS-IS, IE string name = 1
ตัวเลือกดั้งเดิม: ใช้ประเภท wrapper เช่น StringValue name = 1
ข้อความที่จำเป็น: ไม่พร้อมใช้งาน
ข้อความเสริม: ใช้ AS-I, IE SubMessage message = 1