วิธีการทำให้ enum ของสตริงใน Typescript มีค่า key และ value เหมือนกัน
ฉันต้องการสร้างประเภททั่วไปที่ตรวจสอบสิ่งต่อไปนี้ใน enum:
- ทุกฟิลด์เป็นสตริง
- ค่าทั้งหมดเท่ากับกุญแจของตัวเอง
ดังนั้นในกรณีใด ตัวแปร enum ต่อไปนี้จะถือว่าถูกต้อง:
enum correct1 {
bar = 'bar',
baz = 'baz',
}
enum correct2 {
quux = 'quux',
}
แต่สิ่งต่อไปนี้จะไม่:
enum wrongFoo {
bar = 'bar',
baz = 'WRONG',
}
enum wrongFoo2 {
bar = 1
}
ไวยากรณ์ที่ถูกต้องในการทำให้สิ่งนี้เกิดขึ้นคืออะไร?
คำตอบ #1
หากคุณโอเคกับการตรวจสอบเวลาคอมไพล์แบบแมนนวล (ซึ่งหมายความว่าคุณต้องเขียนบางอย่างด้วยตนเองหลังจากการกำหนด enum) คุณสามารถทำสิ่งนี้ได้:
type EnsureCorrectEnum<T extends { [K in Exclude<keyof T, number>]: K }> = true;
จากนั้นให้ตัวคอมไพเลอร์ประเมิน EnsureCorrectEnum<typeof YourEnumObjectHere> หากสามารถคอมไพล์ได้ ดีมาก หากไม่สามารถคอมไพล์ได้ แสดงว่ามีปัญหา:
type Correct1Okay = EnsureCorrectEnum<typeof correct1>; // okay
type Correct2Okay = EnsureCorrectEnum<typeof correct2>; // okay
type WrongFooBad = EnsureCorrectEnum<typeof wrongFoo>; // error!
// ┌─────────────────────────────> ~~~~~~~~~~~~~~~
// Types of property 'baz' are incompatible.
type WrongFoo2Bad = EnsureCorrectEnum<typeof wrongFoo2>; // error!
// ┌──────────────────────────────> ~~~~~~~~~~~~~~~~
// Types of property 'bar' are incompatible.
ข้อผิดพลาดก็อธิบายได้ค่อนข้างชัดเจนเช่นกัน
โอเค หวังว่านี่จะช่วยได้ โชคดีนะ!
ลิงก์ไปยังโค้ด
คำตอบ #2
วิธีทางเลือกที่หลีกเลี่ยงการต้องประกาศชนิดใหม่สำหรับการตรวจสอบแต่ละครั้ง:
const keyValuesMatch = <T>(kv: { [K in keyof T]: K }) => {};
enum correct {
bar = 'bar',
baz = 'baz',
}
enum incorrect {
bar = 'bar',
baz = 'wrong',
}
keyValuesMatch(correct);
keyValuesMatch(incorrect); // Type 'incorrect.baz' is not assignable to type '"baz"'.
