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

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']);