json - การนับประเภทแบบสตริงใน Typescript
ดังนั้นฉันได้อ่านโพสต์ทั้งหมดเกี่ยวกับ Enum แบบสายอักขระใน Typescript แล้ว แต่ฉันไม่สามารถหาวิธีแก้ปัญหาที่ตรงตามความต้องการของฉันได้ ความต้องการเหล่านั้นคือ:
- เอนัมที่ให้การเติมรหัสอัตโนมัติ
- อีนัมที่สามารถวนซ้ำได้
- ไม่ต้องระบุองค์ประกอบซ้ำสองครั้ง
- ขึ้นอยู่กับสตริง
ความเป็นไปได้ที่ฉันได้เห็นจนถึงตอนนี้สำหรับ enums ใน TypeScript มีดังนี้:
enum MyEnum {bla, blub}: สิ่งนี้ล้มเหลวในการเป็นแบบ string-based ดังนั้นผมจึงไม่สามารถอ่านจาก JSONs ซึ่งเป็นแบบ string-based ได้ง่ายๆ…type MyEnum='bla' | 'blub': ไม่สามารถวนรอบและไม่มีการเติมโค้ดอัตโนมัติ- ทำมันด้วยตัวเอง
class MyEnum { static get bla():string{return "bla"} ; static get blub():string{return "blub"}}: ระบุองค์ประกอบสองครั้ง
ดังนั้นนี่คือคำถาม:
- ไม่มีทางที่จะตอบสนองข้อกำหนดเหล่านั้นพร้อมกันได้หรือ? ถ้าไม่ เป็นไปได้ไหมในอนาคต?
- ทำไมพวกเขาไม่ทำ
enumsให้เป็นแบบสตริง? - มีใครเคยประสบปัญหาแบบเดียวกันบ้าง และคุณแก้ไขปัญหาเหล่านั้นอย่างไร?
คำตอบ #1
ฉันคิดว่าการนำ Enum ไปใช้ในสไตล์เหมือน C ที่ใช้ตัวเลขก็โอเค เพราะ Enum (คล้ายกับ Symbol) โดยปกติจะใช้เพื่อประกาศค่าที่สามารถระบุได้อย่างเฉพาะเจาะจงในช่วงเวลาเขียนโปรแกรม วิธีที่เครื่องแสดงค่านั้นในเวลารันจริงไม่ได้เกี่ยวข้องกับนักพัฒนาโดยตรง
แต่ สิ่งที่เราเหล่านักพัฒนาบางครั้งต้องการ (เพราะเราทุกคนขี้เกียจและยังอยากได้ประโยชน์ทั้งหมด!) คือการใช้ Enum เป็น API หรือกับ API ที่ไม่แชร์ Enum นั้นให้กับเรา แม้ว่า API นั้นโดยแท้จริงจะเป็น Enum เพราะค่าที่ถูกต้องของคุณสมบัตินั้นมีเพียง foo และ bar เท่านั้น
ฉันเดาว่านี่คงเป็นเหตุผลว่าทำไมบางภาษาถึงมี Enums ที่อิงจากสตริง :)
วิธีที่ TypeScript จัดการกับ Enum
หากคุณดูที่โค้ด JavaScript ที่ถูกแปลงแล้ว คุณจะเห็นว่า TypeScript ใช้เพียงวัตถุ JavaScript ธรรมดาในการสร้าง Enum ตัวอย่างเช่น:
enum Color {
Red,
Green,
Blue
}
จะถูกแปลงเป็น:
{
0: "Red",
1: "Green",
2: "Blue",
Blue: 2,
Green: 1,
Red: 0
}
ซึ่งหมายความว่าคุณสามารถเข้าถึงค่าของสตริงได้เหมือนกับ Color[Color.Red] คุณยังคงมีการเติมข้อความโค้ดอัตโนมัติและคุณไม่จำเป็นต้องระบุค่าซ้ำสองครั้ง แต่ คุณไม่สามารถทำแค่ Object.keys(Color) เพื่อวนลูปผ่าน Enum ได้ เพราะค่าจะมีอยู่ "สองครั้ง" บนวัตถุนั้น
คำตอบ #2
ทำไมพวกเขาไม่สร้าง enums ให้เป็นแบบสตริง
เพื่อความชัดเจน Enum ทั้งหมดยึดตาม ตัวเลข และ สตริง ในแง่ที่ว่าการเข้าถึงโดยตรงคือ ตัวเลข และแผนที่ย้อนกลับคือ สตริง (มีรายละเอียดเพิ่มเติมเกี่ยวกับเรื่องนี้)
ตอบสนองความต้องการของคุณ
เหตุผลหลักของคุณในการตัดตัวเลขจำนวนเต็มดิบออกคือ
ดังนั้นฉันจึงไม่สามารถอ่านจาก JSON ที่มีพื้นฐานเป็นสตริงได้โดยตรง...
คุณจะพบประสบการณ์เหมือนกัน เช่น เมื่ออ่าน Date เนื่องจาก JSON ไม่มีชนิดข้อมูลวันที่ คุณจะต้องใช้ new Date("someServerDateTime") เพื่อแปลงสิ่งเหล่านี้
คุณจะใช้กลยุทธ์เดียวกันในการเปลี่ยนจาก enum (สตริง) ฝั่งเซิร์ฟเวอร์ไปเป็น enum (ตัวเลข) ใน TS ทำได้ง่าย ๆ ขอบคุณการค้นหากลับ MyEnum["someServerString"]
การให้ความชุ่มชื้น
กระบวนการแปลงข้อมูลฝั่งเซิร์ฟเวอร์เป็นข้อมูล active ฝั่งลูกค้านี้บางครั้งเรียกว่า Hydration ไลบรารีที่ฉันชอบสำหรับสิ่งนี้ในขณะนี้คือ https://github.com/pleerock/class-transformer
ฉันจัดการเรื่องพวกนี้เองโดยตรงในระดับ การเข้าถึงเซิร์ฟเวอร์ คือเขียน API ด้วยมือที่ทำ XHR และทำการซีเรียลไลซ์
ที่งานล่าสุดของฉัน เราได้ทำให้สิ่งนี้เป็นอัตโนมัติด้วยการสร้างโค้ดที่ทำได้มากกว่านั้น (รองรับรูปแบบการตรวจสอบทั่วไประหว่างโค้ดฝั่งเซิร์ฟเวอร์และไคลเอนต์)
