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

TypeScript ดัชนีลายเซ็นกับคุณสมบัติที่ทราบของชนิดผสม


วิธีระบุลายเซ็นดัชนีด้วยคุณสมบัติที่ทราบชนิดที่กำหนดและคุณสมบัติอื่น ๆ ทั้งหมดที่มีชนิดแตกต่างกัน ตัวอย่างต่อไปนี้ทำงานตามที่คาดหวังด้วย as any แต่ล้มเหลวเมื่อระบุคุณสมบัติทั้งหมด:

type S = {
    s?: number;
} 
type H = {
    [key: string]: Function | undefined;
}
type Handler = S & H


const h1: Handler = {} as any;

/* Ok */
h1.sadwa?.()
h1.s = 2;


/* Not ok */
const h2: Handler = {
    s:  22,
    f: ()=>{}
}
h2.f()
h2.s = 2;

https://www.typescriptlang.org/play?#code/C4TwDgpgBAylC8UDeAoK6oGcD8AuKAdgK4C2ARhAE4DcKAvlCqJFABILJoYDaA1hCHyZglAJYEA5gF18AMSIEAxsFEB7AlAA+UBQBMIAM3ERdtOk3DRWAQwK6ANlQ5wAZGxQfF64VAAWARnwbO0dKDiQGa0woWxBaFAB6ACooAHleKCSElACAOkxrXQB3a2xcgAoAShz-fI4AJnjElIA5VWAoVQyslC8CH196oNsHJ0RUDCx8KHr6gBoudAN8KvgAPgj6HPrcgyrtusRGoA

คำตอบ #1

ฉันได้อ่านเกี่ยวกับสิ่งที่ Index Signature สามารถทำได้ มันคืออะไร และสิ่งที่มันทำไม่ได้

วิธีเดียวที่คุณจะทำให้ตัวอย่างนี้ใช้งานได้คือหากประเภทที่ระบุในค่าของลายเซ็นดัชนีครอบคลุมประเภทอื่นทั้งหมดที่ระบุในวัตถุ

ตัวอย่างเช่น:

type S = {
    s?: number;
} 
type H = {
    [key: string]: Function | undefined | number;
}
type Handler = S & H

// Incedentally the above is the same as this type
type AnotherHandler = {
    s?: number;
    [key: string]: Function | undefined | number
}

// Works just fine
const h2: Handler = {
    s:  22,
    f: ()=>{}
}
h2.f()
h2.s = 2;

นี่เกี่ยวข้องกับสิ่งที่เรียกว่า Index Signature โดยหลักการ ดัชนีของวัตถุเป็นแผ่นอ้างอิงสำหรับทุกสิ่งที่วัตถุมี ลายเซ็นของมันได้รับประกันว่าจะตรงกับทุกประเภทค่าของวัตถุ คำอธิบายนั้นค่อนข้างทำให้ง่ายขึ้น แต่ใช้ได้กับตัวอย่างนี้

ถ้าคุณไม่อยากทำอย่างนั้น แต่ต้องการอย่างน้อยที่จะแก้ไขปัญหาเรื่องประเภท คุณสามารถหลีกเลี่ยงการตรวจสอบประเภทได้โดยการประกาศวัตถุโดยไม่มีประเภทเหมือนที่คุณทำกับ h1 จากนั้นใช้ประโยชน์จากการตรวจสอบประเภทที่ผ่อนคลายมากขึ้นซึ่งเกิดขึ้นเมื่อคุณใช้วัตถุนั้นในตำแหน่งที่ต้องการประเภทของคุณ (กฎที่แน่นอนคือ ตราบใดที่วัตถุที่คุณใช้มีคู่คีย์:ค่าที่ถูกต้องอย่างน้อยหนึ่งคู่เหมือนกับประเภทที่ใช้ ประเภทอื่นใดที่ผสมเข้ามาจะไม่ล้มเหลวในการตรวจสอบ)