ข้อความข้อผิดพลาดใน DSL ระดับชนิดข้อมูล
แสดงข้อผิดพลาดขณะคอมไพล์ที่เป็นประโยชน์แก่ผู้ใช้ DSL
ข้อความข้อผิดพลาดใน DSL ระดับชนิดข้อมูล เป็นบทเรียน TypeScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน TypeScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
ข้อผิดพลาดที่เข้าใจง่ายใน DSL ระดับชนิดข้อมูล
ส่วนที่ยากที่สุดของ DSL ระดับชนิดข้อมูลคือการทำให้ความล้มเหลว อ่านเข้าใจได้ ข้อผิดพลาดดิบอย่าง never หรือ "ไม่สามารถกำหนดให้กับ" ทำให้ผู้ใช้สับสน เราจึงแสดงข้อผิดพลาดที่อธิบายได้ด้วย ชนิดข้อผิดพลาดที่มีตราประทับ และข้อความ never ที่สร้างขึ้นโดยเฉพาะ
ปัญหาของ never
เมื่อการตรวจสอบล้มเหลวโดยกลายเป็น never คอมไพเลอร์จะบอกว่า "อาร์กิวเมนต์ชนิด X ไม่สามารถกำหนดให้กับ never ได้" ซึ่งไม่ได้บอกผู้ใช้ว่า เพราะเหตุใด เราทำให้ดีกว่านี้ได้
ชนิดข้อผิดพลาดที่มีตราประทับ
แทนที่จะส่งคืน never ธรรมดา ให้ส่งคืนชนิดข้อผิดพลาดที่มีรูปแบบเฉพาะและมีสตริงข้อความที่มนุษย์อ่านเข้าใจได้อยู่ในชนิดนั้น
type TypeError<Msg extends string> = {
readonly __error: Msg;
};
type E = TypeError<"Column 'foo' does not exist">;การส่งคืนข้อผิดพลาดจากการตรวจสอบ
ตัวตรวจสอบจะส่งคืนชนิดค่าที่ถูกต้องหรือข้อผิดพลาดที่มีตราประทับ ซึ่งอธิบายปัญหา การตรวจสอบ "มีจุด" เป็นรูปแบบลิเทอรัลแม่แบบ (ในโค้ดจริงใช้แบ็กทิก) เราเรียกแทนด้วย HasDot
// HasDot<S> is the backtick pattern: any text, ".", any text.
type Validate<S extends string> =
S extends HasDot
? S
: TypeError<"Path must contain a dot, e.g. user.name">;การบังคับให้ข้อผิดพลาดแสดงขึ้น
จำกัดพารามิเตอร์เพื่อให้การส่งสิ่งใดก็ตามที่ไม่สามารถกำหนดให้กับตราประทับข้อผิดพลาดได้ แสดงข้อความดังกล่าว ชนิดข้อผิดพลาดจะปรากฏโดยตรงในผลลัพธ์ของคอมไพเลอร์
declare function path<S extends string>(
p: Validate<S> extends TypeError<infer M> ? TypeError<M> : S
): void;
path("oops");
// Error message includes: __error: "Path must contain a dot..."การแยกแยะข้อผิดพลาดหลายรูปแบบ
ความล้มเหลวแต่ละรูปแบบจะส่งคืนข้อความที่แตกต่างกัน ผู้ใช้จึงได้รับคำแนะนำที่เฉพาะเจาะจงแทนการถูกปฏิเสธด้วยข้อความทั่วไปเพียงข้อความเดียว HasDot ยังคงเป็นรูปแบบลิเทอรัลแม่แบบแบบแบ็กทิกสำหรับ "มีจุดอยู่ภายใน"
type Check<S extends string> =
S extends "" ? TypeError<"Path cannot be empty">
: S extends HasDot ? S
: TypeError<"Missing dot separator">;never ในรูปแบบใหม่
อีกเทคนิคหนึ่งคือจับคู่ตำแหน่งค่ากับข้อความลิเทอรัล เพื่อให้การวางเมาส์เหนือค่าดังกล่าวแสดงข้อความนั้น คุณนำชนิดที่ก่อปัญหาไปตัดกับออบเจกต์ที่มีป้ายกำกับ
type Invalid<M extends string> = { error: M } & never;
// using never keeps it unassignable while the label hints the causeข้อผิดพลาดใน DSL แบบต่อโซ่
ใน DSL ที่เรียกต่อกัน ให้ขั้นถัดไปที่ไม่ถูกต้องส่งคืนชนิดที่มีตราประทับข้อผิดพลาดแทนขั้นที่ถูกต้อง เพื่อให้ตัวแก้ไขแสดงข้อความตรงจุดที่เกิดข้อผิดพลาด
interface Stage {
// calling done() before where() yields a labeled error
done(): TypeError<"Call .where() before .done()">;
}การรักษาข้อความให้สั้น
ชนิดข้อความที่ยาวจะทำให้ผลลัพธ์ของคอมไพเลอร์มีขนาดใหญ่และทำให้เครื่องมือทำงานช้าลง ควรเลือกใช้วลีที่กระชับและนำไปปฏิบัติได้ หากเพิ่มโทเค็นที่ก่อปัญหาได้โดยไม่ยุ่งยากก็ควรเพิ่ม แต่หลีกเลี่ยงการแทรกข้อความขนาดใหญ่
การทดสอบข้อผิดพลาด
เขียนการทดสอบระดับชนิดข้อมูลเพื่อยืนยันว่าข้อผิดพลาดที่มีตราประทับปรากฏขึ้นสำหรับอินพุตที่ทราบว่าไม่ถูกต้อง เพื่อให้การปรับโครงสร้างไม่ทำให้ประสบการณ์ของนักพัฒนาลดลงโดยไม่รู้ตัว
type Expect<T extends true> = T;
type _t = Expect<Validate<"oops"> extends TypeError<any> ? true : false>;เหตุผลที่เรื่องนี้สำคัญ
DSL จะดีได้เท่ากับข้อผิดพลาดของมันเท่านั้น ชนิดข้อผิดพลาดที่มีตราประทับเปลี่ยนความล้มเหลวแบบ never ที่เข้าใจยากให้เป็นข้อความที่ อธิบายตัวเองได้ และช่วยยกระดับประสบการณ์การใช้ API ระดับชนิดข้อมูลของคุณอย่างมาก
ตรวจสอบความเข้าใจอย่างรวดเร็ว
ยืนยันความเข้าใจของคุณเกี่ยวกับข้อความข้อผิดพลาดระดับชนิดข้อมูล
ทบทวน
เพื่อให้ DSL ระดับชนิดข้อมูลใช้งานได้สะดวก ให้แทนที่ never เปล่าด้วย ชนิดข้อผิดพลาดที่มีตราประทับ ซึ่งฝังข้อความที่อ่านเข้าใจได้ ตัวตรวจสอบจะส่งคืนชนิดที่ถูกต้องหรือประทับข้อผิดพลาดเฉพาะอย่างใดอย่างหนึ่ง การจำกัดพารามิเตอร์จะทำให้ข้อความปรากฏในผลลัพธ์ของคอมไพเลอร์ ควรรักษาข้อความให้สั้นและเขียนการทดสอบให้ข้อความเหล่านั้นด้วย
คำถามที่พบบ่อย
บทเรียน “ข้อความข้อผิดพลาดใน DSL ระดับชนิดข้อมูล” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ข้อความข้อผิดพลาดใน DSL ระดับชนิดข้อมูล” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส TypeScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ข้อความข้อผิดพลาดใน DSL ระดับชนิดข้อมูล”
แสดงข้อผิดพลาดขณะคอมไพล์ที่เป็นประโยชน์แก่ผู้ใช้ DSL คุณปฏิบัติ TypeScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน TypeScript Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน TypeScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “ข้อความข้อผิดพลาดใน DSL ระดับชนิดข้อมูล” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน TypeScript Academy นี้ได้ไหม
ได้ บทเรียน TypeScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- DSL ระดับชนิดข้อมูลคืออะไร
- การออกแบบ DSL สำหรับการสืบค้นแบบต่อเนื่อง
- การตรวจสอบ input เวลาคอมไพล์
- ข้อความข้อผิดพลาดใน DSL ระดับชนิดข้อมูล