typescript - การเชนแบบไม่บังคับสำหรับอินเทอร์เฟซที่มีดัชนีลายเซ็นต์
ฉันกำหนดอินเทอร์เฟซสองตัว อินเทอร์เฟซตัวแรกมีฟิลด์ที่เป็นตัวเลือก อินเทอร์เฟซตัวที่สองมีสัญลักษณ์ดัชนี:
interface A {
foo?: { bar: number };
}
interface B {
[s: string]: { bar: number };
}
ทำไมอินเทอร์เฟซแรกถึงให้ผลลัพธ์เป็นประเภท number | undefined เมื่อฉันเข้าถึงคุณสมบัติด้วยการเชนแบบเลือกได้ ในขณะที่อินเทอร์เฟซที่สองให้เพียงประเภท number เท่านั้น?
const a: A = {};
const aa = a.foo?.bar;
// const aa: number | undefined
const b: B = {};
const bb = b.foo?.bar;
// const bb: number
คำตอบ #1
เนื่องจาก B ถูกจัดทำดัชนีโดย [s: string] มันจึงเชื่อว่าคีย์สตริงที่ถูกต้องใด ๆ จะทำให้สามารถเข้าถึงค่าของ { bar: number } ดังนั้น ด้วย
const b: B = {};
const bb = b.foo?.bar;
มันคิดว่า property foo จะมีอยู่เสมอ - มันจะไม่ล้มเหลวและกลายเป็น undefined ผ่าน optional chaining
ในทางตรงกันข้าม กับของ A:
interface A {
foo?: { bar: number };
}
เนื่องจากคุณสมบัติ foo เป็นตัวเลือกที่นี่ มัน ไม่ แน่ใจว่าจะมีอยู่ (สำหรับ Typescript) ดังนั้น ?. อาจส่งผลให้ไม่พบคุณสมบัติใด ๆ และ undefined เป็นผลลัพธ์
คุณสามารถทำให้ชัดเจนว่าไม่ใช่ทุกคุณสมบัติบน B จะต้องมีวัตถุ bar โดยการสลับกับ undefined ในประเภทค่าของวัตถุ:
interface B {
[s: string]: { bar: number } | undefined;
}
ส่งผลให้ bb ถูกพิมพ์เป็น number | undefined
คำตอบ #2
ในกรณีที่คุณกำลังเลือกทรัพย์สินที่มีอยู่:
interface SomeInterface {
prop1: string;
prop2: string;
}
จากนั้นคุณสามารถใช้ไวยากรณ์ ?.[:
var o: SomeInterface = {
prop1: 'test',
prop2: 'test2'
}
console.log(o?.['prop1']);
