ชนิด never และสถานะที่เป็นไปไม่ได้
จำลองโค้ดที่ไม่สามารถเข้าถึงได้และค่าที่เป็นไปไม่ได้ด้วย never
ชนิด never และสถานะที่เป็นไปไม่ได้ เป็นบทเรียน TypeScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน TypeScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
ชนิด never
never คือชนิดว่างเปล่า ซึ่งแสดงถึงค่าที่ไม่สามารถเกิดขึ้นได้ ไม่มีค่าใดสามารถกำหนดให้กับ never ได้ (ยกเว้น never เอง) ชนิดนี้ใช้ระบุสถานการณ์ที่ควรเป็นไปไม่ได้
// You cannot create a value of type never
function crash(): never {
throw new Error('boom');
}
try { crash(); } catch (e) { console.log('caught'); }ฟังก์ชันที่ไม่คืนค่าเลย
ฟังก์ชันที่ทำ throw เสมอจะไม่คืนค่าตามปกติ ดังนั้นชนิดค่าที่คืนจึงเป็น never ซึ่งบอกผู้เรียกและคอมไพเลอร์ว่าการทำงานจะหยุดลงที่จุดนี้
function fail(message: string): never {
throw new Error(message);
}
try { fail('invalid'); } catch (e) { console.log('handled'); }ลูปไม่สิ้นสุดคืนค่าเป็น never
ฟังก์ชันที่มีลูปไม่สิ้นสุดก็จะไม่คืนค่าเช่นกัน จึงมีชนิดเป็น never คอมไพเลอร์รู้ว่าลำดับการควบคุมไม่สามารถดำเนินต่อหลังจากฟังก์ชันนี้ได้
function listen(): never {
while (true) {
// forever
break; // (break added so the demo terminates)
}
throw new Error('stopped');
}
console.log('listen has return type never');never กับ void
อย่าสับสนระหว่าง never กับ void ฟังก์ชันชนิด void ยังคงคืนค่า เพียงแต่ค่านั้นไม่มีประโยชน์สำหรับผู้เรียก ส่วนฟังก์ชันชนิด never ไม่คืนค่าเลย แต่จะโยนข้อผิดพลาดหรือลูปไปตลอด
function logIt(): void {
console.log('done'); // returns normally
}
function abort(): never {
throw new Error('stop'); // never returns
}
logIt();
try { abort(); } catch (e) { console.log('ok'); }never ในการตรวจสอบความครอบคลุมทุกกรณี
การใช้งาน never ที่เป็นประโยชน์ที่สุดคือการตรวจสอบความครอบคลุมทุกกรณี ในค่าเริ่มต้นของ switch ให้กำหนดตัวแปรเป็น never หากจัดการครบทุกกรณีแล้ว ตัวแปรนั้นจะเป็น never อยู่แล้ว และโค้ดจะคอมไพล์ผ่าน
type Shape = 'circle' | 'square';
function area(s: Shape): string {
switch (s) {
case 'circle': return 'pi r^2';
case 'square': return 'a^2';
default:
const _check: never = s; // ok: all handled
return _check;
}
}
console.log(area('square'));ตรวจจับกรณีที่ขาดหาย
หากมีคนเพิ่มสมาชิกใหม่ในยูเนียนแต่ลืมเพิ่มกรณีที่เกี่ยวข้อง ค่าที่เหลือจะไม่ใช่ never อีกต่อไป การกำหนดค่าจึงคอมไพล์ไม่ผ่าน การตรวจสอบด้วย never เปลี่ยนช่องว่างที่ไม่แจ้งเตือนให้กลายเป็นข้อผิดพลาดที่เห็นได้ชัด
type Shape = 'circle' | 'square' | 'triangle';
// If 'triangle' case is missing, assigning s to never
// would error: 'triangle' is not assignable to never.
console.log('Add a case for every member');never ในแขนงที่เป็นไปไม่ได้ของยูเนียน
เมื่อการทำให้ชนิดแคบลงตัดความเป็นไปได้ออกทั้งหมด ชนิดที่เหลือจะเป็น never คอมไพเลอร์รู้ว่าแขนงนั้นไม่สามารถเข้าถึงได้ ซึ่งอาจช่วยเปิดเผยข้อผิดพลาดด้านตรรกะ
function check(x: string | number): void {
if (typeof x === 'string') {
console.log('string');
} else if (typeof x === 'number') {
console.log('number');
} else {
// x is never here
console.log('unreachable');
}
}
check('hi');never ในฐานะชนิดล่างสุด
never คือชนิดล่างสุด ซึ่งสามารถกำหนดให้กับชนิดอื่นได้ทุกชนิด เพราะค่าที่ไม่สามารถมีอยู่ได้ย่อมเข้ากันได้กับทุกสิ่งโดยปริยาย นี่คือเหตุผลที่ throw สามารถปรากฏในตำแหน่งนิพจน์ใด ๆ ได้
function getOrThrow(v: string | null): string {
return v ?? fail();
}
function fail(): never {
throw new Error('missing');
}
console.log(getOrThrow('value'));กรองยูเนียนให้เหลือ never
ในชนิดแบบมีเงื่อนไขและชนิดแบบแมป never มีความหมายคล้ายการลบสิ่งนั้นออก การรวมยูเนียนกับ never ไม่เปลี่ยนแปลงอะไร: T | never เป็นเพียง T วิธีนี้ทำให้ never เป็นตัวเลือกที่เหมาะสมสำหรับการกรอง
type Keep<T> = T extends string ? T : never;
type R = Keep<'a' | 1 | 'b'>; // 'a' | 'b'
const x: R = 'a';
console.log(x);จำลองสถานะที่เป็นไปไม่ได้
ใช้ never ในโครงสร้างอ็อบเจ็กต์เพื่อทำให้ชุดค่าผสมที่ผิดกฎไม่สามารถแทนค่าได้ ในกรณีนี้ สถานะกำลังโหลดจะไม่สามารถมีข้อมูลอยู่พร้อมกันได้ เพราะชนิดข้อมูลห้ามไว้
type State =
| { status: 'loading'; data?: never }
| { status: 'ready'; data: number };
const s: State = { status: 'ready', data: 7 };
console.log(s);never ช่วยให้การปรับโครงสร้างปลอดภัยขึ้น
เนื่องจากการตรวจสอบความครอบคลุมด้วย never จะล้มเหลวเมื่อมีกรณีตกหล่น การตรวจสอบนี้จึงช่วยให้การปรับโครงสร้างปลอดภัยขึ้น เมื่อขยายยูเนียน คอมไพเลอร์จะชี้ให้เห็นทุกจุดที่ต้องอัปเดต
type Cmd = 'start' | 'stop';
function run(c: Cmd): string {
if (c === 'start') return 'starting';
if (c === 'stop') return 'stopping';
const _x: never = c;
return _x;
}
console.log(run('start'));ตรวจสอบความเข้าใจอย่างรวดเร็ว
ทดสอบความเข้าใจเรื่องชนิด never
สรุป: ชนิดที่ไม่มีทางเกิดขึ้น
คุณได้เรียนรู้ว่า never:
- เป็น ชนิดว่างเปล่า — ไม่มีค่าใดมีชนิดนี้
- เป็นชนิดค่าที่ส่งกลับของฟังก์ชันที่โยนข้อผิดพลาดหรือลูปไม่สิ้นสุด
- ช่วยขับเคลื่อน การตรวจสอบความครบถ้วน ในส่วนค่าเริ่มต้นของคำสั่งสลับ
- ปรากฏในแขนงการจำแนกชนิดที่เป็นไปไม่ได้ และกรองยูเนียนในตรรกะชนิด
ต่อไป เราจะดูชนิด void และความแตกต่างของชนิดนี้
function assertNever(x: never): never {
throw new Error('Unexpected: ' + String(x));
}
console.log('assertNever guards exhaustiveness');คำถามที่พบบ่อย
บทเรียน “ชนิด never และสถานะที่เป็นไปไม่ได้” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ชนิด never และสถานะที่เป็นไปไม่ได้” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส TypeScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ชนิด never และสถานะที่เป็นไปไม่ได้”
จำลองโค้ดที่ไม่สามารถเข้าถึงได้และค่าที่เป็นไปไม่ได้ด้วย never คุณปฏิบัติ TypeScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน TypeScript Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน TypeScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “ชนิด never และสถานะที่เป็นไปไม่ได้” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน TypeScript Academy นี้ได้ไหม
ได้ บทเรียน TypeScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ทำความเข้าใจ unknown เทียบกับ any
- ชนิด never และสถานะที่เป็นไปไม่ได้
- ชนิด void ในฟังก์ชัน
- การจัดการ unknown อย่างปลอดภัยด้านชนิดข้อมูล