javascript - ทำไม TypeScript จึงพิจารณาว่าตัวเลขแต่ละตัวเป็นชนิดของตัวเอง?
นิพจน์ 1==2 ทำให้ TypeScript แสดงข้อผิดพลาด Operator '==' cannot be applied to types '1' and '2' เหตุผลที่ TypeScript จัดให้ค่าพวกนี้เป็นประเภทต่างกันคืออะไร (ตัวดำเนินการ typeof อย่างที่คาดไว้ บอกว่าทั้งคู่เป็น number) นี่เป็นการตัดสินใจเชิงออกแบบเพื่อใช้เฉพาะกับตัวเลขหรือเป็นผลพลอยได้จากระบบการพิมพ์โดยรวม? การอนุญาตให้เปรียบเทียบลิเทอรัลอาจก่อให้เกิดอันตรายอะไรได้บ้าง?
คำตอบ #1
1 และ 2 ในบริบทนี้ถือว่าเป็นตัวเลขที่เรียกว่า literal หมายความว่าค่า 1 มีชนิดเป็น 1 และจึงสามารถเป็นได้แค่ 1 เหมือนกันกับ 2 จากนั้น นิพจน์ 1==2 จึงไม่มีความหมายเพราะ 1 ไม่มีทางเป็น 2 หรือเจาะจงมากกว่านั้นคือชนิดของพวกมันไม่ตรงกัน คุณไม่สามารถเปรียบเทียบแอปเปิ้ลกับส้มได้
นี่คือเหตุผลและรายละเอียดเชิงลึกเกี่ยวกับที่ซึ่งประเภทลิตเตอรัลถูกสมมติไว้ตามค่าเริ่มต้น:
- https://github.com/Microsoft/TypeScript/pull/10676
เกี่ยวกับประเภทตัวอักษรตรงตัว:
- https://github.com/Microsoft/TypeScript/pull/9407
- https://github.com/Microsoft/TypeScript/pull/5185
ตัวอย่างหนึ่งจากหลายตัวอย่างว่าทำไมประเภทตัวอักษรตรงตัวจึงมีประโยชน์:
- https://github.com/Microsoft/TypeScript/pull/9163
คำตอบ #2
เมื่อ TypeScript ทำการอนุมานชนิดข้อมูล (type inference) ในนิพจน์ 1 มันจะให้ชนิดเป็น 1 ไม่ใช่ชนิด number คุณสามารถเห็นสิ่งนี้ได้หากคุณตรวจสอบโค้ดเช่นนี้:
const a = 1;
หากคุณใช้ IDE ของคุณในการสอบถามประเภทที่คาดเดาของ a คุณจะเห็นว่าประเภทของ a คือ 1 ใน TypeScript playground ตัวอย่างเช่น คุณจะได้รับคำแนะนำที่บอกว่า const a: 1
ดังนั้นใน if (1 == 2), 1 มีชนิดเป็น 1 และ 2 มีชนิดเป็น 2. TypeScript ไม่อนุญาตให้คุณเปรียบเทียบพวกมันเพราะพวกมันมีชนิดที่ถูกอนุมานต่างกัน นี่เป็นส่วนหนึ่งของความปลอดภัยด้านชนิดที่ TypeScript มอบให้คุณ
คุณ สามารถแก้ไขปัญหานี้ได้ด้วย:
if (1 as number == 2) {
}
และคุณได้กล่าวในความคิดเห็นว่าคุณกำลังทำการเปรียบเทียบ 1 == 2 เพราะคุณไม่สามารถทำ if (false) { ... } ได้เนื่องจากคอมไพเลอร์แจ้งข้อผิดพลาดเกี่ยวกับโค้ดที่เข้าถึงไม่ได้ ผมสามารถแก้ปัญหานั้นได้ด้วยวิธีนี้:
if (false as boolean) {
console.log("something");
}
