ค้นหาเว็บไซต์

javascript - การประกาศชนิดทำงานกับ object literal แต่ไม่ทำงานกับการใช้งานคลาส


ฉันต้องการชนิดข้อมูลเพื่อแทนค่าพิกัด ชนิดข้อมูลที่ฉันนำไปใช้กับอินเทอร์เฟซนั้นใช้ได้กับอ็อบเจ็กต์แต่ไม่สามารถใช้กับคลาสได้

type ICoord = [number, number]

type MyInterface = {
    a: ICoord
}

var obj: MyInterface = { // works
    a: [0, 0]
}

class C implements MyInterface { // gets below compilation error
    a = [0, 0]
}

คุณสมบัติ 'a' ในประเภท 'C' ไม่สามารถกำหนดค่าให้กับคุณสมบัติเดียวกันในประเภทฐาน 'MyInterface' ได้ ประเภท 'number[]' ขาดคุณสมบัติต่อไปนี้จากประเภท '[number, number]': 0, 1

ทำไมฉันถึงไม่สามารถกำหนดค่า [0, 0] ให้กับ a ได้?

[สนามเด็กเล่น TypeScript]

คำตอบ #1

ประเภทของ a ถูกสันนิษฐานว่าเป็น number[] ซึ่งไม่สามารถกำหนดค่าให้กับทูเพิล [number, number] ได้ การกำหนดประเภทแบบชัดเจนเป็น ICoord สำหรับ a ดูเหมือนว่าจะใช้ได้:

type ICoord = [number, number];

type MyInterface = {
  a: ICoord;
}

class C implements MyInterface {
  a: ICoord = [0, 0];
}

สนามเด็กเล่น TypeScript

คำตอบ #2

นี่เกี่ยวข้องกับการพิมพ์ตามบริบท

Typescript ใช้ประเภทที่คาดหวังของนิพจน์ (MyInterface ในกรณีนี้) เพื่อทำการอนุมานที่ดีกว่าเกี่ยวกับออบเจกต์ลิเทอรัล (รวมถึงพารามิเตอร์ฟังก์ชันด้วย) นี่คือเหตุผลว่าทำไมการกำหนดค่าออบเจกต์ลิเทอรัลจึงทำงานได้ดี และแอเรย์ลิเทอรัลถูกพิมพ์เป็นประเภททูเพิล

สำหรับคลาส สิ่งต่าง ๆ จะแตกต่างออกไปเล็กน้อย ส่วน implements ใช้เพื่อตรวจสอบว่าคลาสนั้นทำการใช้งานอินเทอร์เฟซอย่างถูกต้องหลังจากที่คลาสถูกพิมพ์ชนิดอย่างอิสระแล้ว คำสำคัญ implements จะไม่สร้างการพิมพ์บริบทใด ๆ สำหรับสมาชิกของคลาส นี่ก็เป็นสาเหตุที่คุณต้องระบุชนิดของพารามิเตอร์ฟังก์ชันแม้ว่าจะสามารถเดาได้จากอินเทอร์เฟซหรือคลาสพื้นฐาน

บทความที่เกี่ยวข้อง