ปัญหาของการโยนข้อผิดพลาด
ทำความเข้าใจว่าเหตุใดข้อยกเว้นจึงซ่อนความล้มเหลวจากระบบชนิดข้อมูล
ปัญหาของการโยนข้อผิดพลาด เป็นบทเรียน TypeScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน TypeScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
ข้อยกเว้นมองไม่เห็น
เมื่อฟังก์ชันใช้ throw ลายเซ็นของฟังก์ชันจะไม่ระบุเรื่องนี้ ระบบชนิดข้อมูลมองไม่เห็น ว่าฟังก์ชันใดอาจล้มเหลว ดังนั้นผู้เรียกจึงไม่มีคำเตือนจากคอมไพเลอร์ให้จัดการข้อผิดพลาด
ฟังก์ชันที่ส่งข้อยกเว้น
ฟังก์ชันนี้ดูเหมือนจะคืนค่าตัวเลขเสมอ แต่สามารถส่งข้อยกเว้นได้ ชนิดข้อมูลที่คืนค่าเป็น number จึงซ่อนกรณีที่ล้มเหลวไว้อย่างสมบูรณ์
function parsePort(s: string): number {
const n = Number(s);
if (Number.isNaN(n)) throw new Error("bad port");
return n;
}
console.log(parsePort("8080")); // 8080ผู้เรียกลืมดักจับ
ไม่มีสิ่งใดบังคับให้ผู้เรียกครอบการเรียกใช้ด้วย try/catch ความผิดพลาดนี้คอมไพล์ผ่านอย่างเรียบร้อย และจะปรากฏขึ้นในรูปของโปรแกรมหยุดทำงานเมื่อรันจริงเท่านั้น
const port = parsePort("oops");
// No compile error; throws at runtime, possibly crashing the app.try/catch ทำให้ชนิดข้อมูลหายไป
แม้จะดักจับแล้ว ค่าที่ดักจับได้ก็มีชนิดเป็น unknown (หรือ any) รูปแบบของข้อผิดพลาดไม่ได้ถูกติดตามไว้ จึงต้องคาดเดาวิธีจัดการ
try {
parsePort("x");
} catch (e) {
// e: unknown -> you must narrow it manually
}ข้อผิดพลาดในรูปค่า
ทางเลือกคือทำให้การล้มเหลวเป็น ค่า ปกติที่ฟังก์ชันคืนกลับมา แทนที่จะเป็นข้อยกเว้นที่ฟังก์ชันส่งออกไป จากนั้นชนิดข้อมูลที่คืนค่าจะบอกผลลัพธ์ทั้งสองแบบอย่างตรงไปตรงมา
โครงร่างการคืนค่า
แทนที่จะส่งข้อยกเว้น ให้คืนอ็อบเจ็กต์ที่มีแท็กเพื่ออธิบายว่าดำเนินการสำเร็จหรือล้มเหลว ผู้เรียกต้องตรวจสอบอ็อบเจ็กต์นี้ก่อนนำค่าไปใช้
type ParseResult =
| { ok: true; value: number }
| { ok: false; error: string };ตอนนี้ชนิดข้อมูลบอกความจริง
ฟังก์ชันที่คืนค่า ParseResult ประกาศอย่างชัดเจนว่าอาจล้มเหลวได้ จากนั้นคอมไพเลอร์จะบังคับให้ผู้เรียกจัดการแขนงที่ล้มเหลว
function parsePort(s: string): ParseResult {
const n = Number(s);
return Number.isNaN(n)
? { ok: false, error: "bad port" }
: { ok: true, value: n };
}บังคับให้จัดการ
เนื่องจากค่าอาจเป็นแขนงใดแขนงหนึ่ง คุณจึงอ่าน value ไม่ได้จนกว่าจะตรวจสอบ ok ก่อน คอมไพเลอร์จะจำกัดชนิดข้อมูลให้แคบลงหลังจากตรวจสอบแล้วเท่านั้น
const r = parsePort("oops");
if (r.ok) console.log(r.value);
else console.log("failed:", r.error);ข้อยกเว้นยังมีที่ใช้งาน
ความล้มเหลวที่ไม่คาดคิดและไม่สามารถกู้คืนได้อย่างแท้จริง (เช่น ข้อผิดพลาดของผู้เขียนโปรแกรมหรือหน่วยความจำไม่พอ) ยังคงส่งข้อยกเว้นได้ ส่วนข้อผิดพลาดในรูปค่าจะเหมาะอย่างยิ่งกับความล้มเหลวที่ คาดหมายได้ เช่น การแยกวิเคราะห์และการตรวจสอบความถูกต้อง
ชัดแจ้งเหนือสิ่งโดยนัย
การคืนข้อผิดพลาดทำให้เส้นทางความล้มเหลวปรากฏอย่างชัดเจนในชนิดข้อมูล มองเห็นได้ตรงจุดเรียกใช้ และไม่อาจถูกละเลยโดยไม่ได้ตั้งใจ ต่างจาก throw ที่ซ่อนอยู่
มุ่งสู่ Result และ Option
รูปแบบที่มีแท็กสำหรับความสำเร็จหรือความล้มเหลวนี้ต่อยอดเป็นชนิดข้อมูล ผลลัพธ์ ที่นำกลับมาใช้ซ้ำได้ ส่วนการมีค่าหรือไม่มีค่าต่อยอดเป็น ตัวเลือก ทั้งสองหัวข้อจะกล่าวถึงในลำดับถัดไป
ตรวจสอบความเข้าใจ
ตรวจสอบความเข้าใจบทเรียนนี้อย่างรวดเร็ว
ทบทวน
ข้อผิดพลาดที่ส่งออกมานั้น มองไม่เห็น สำหรับชนิดข้อมูล เพราะลายเซ็นซ่อนความล้มเหลวไว้และผู้เรียกอาจลืมดักจับ การคืนความล้มเหลวเป็น ค่าที่ชัดแจ้ง (อ็อบเจ็กต์ที่มีแท็กบอกความสำเร็จหรือข้อผิดพลาด) ทำให้เส้นทางความล้มเหลวปรากฏในชนิดข้อมูลและไม่อาจถูกละเลย นำไปสู่ชนิดข้อมูล Result และ Option
คำถามที่พบบ่อย
บทเรียน “ปัญหาของการโยนข้อผิดพลาด” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ปัญหาของการโยนข้อผิดพลาด” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส TypeScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ปัญหาของการโยนข้อผิดพลาด”
ทำความเข้าใจว่าเหตุใดข้อยกเว้นจึงซ่อนความล้มเหลวจากระบบชนิดข้อมูล คุณปฏิบัติ TypeScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน TypeScript Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน TypeScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “ปัญหาของการโยนข้อผิดพลาด” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน TypeScript Academy นี้ได้ไหม
ได้ บทเรียน TypeScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ปัญหาของการโยนข้อผิดพลาด
- การจำลองชนิดข้อมูล Result
- ชนิดข้อมูล Option และ Maybe
- การเขียนโปรแกรมแบบ Railway-Oriented