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

วิธีทำให้ Typescript รับรู้ความคล้ายคลึงทั่วไประหว่างสองอินเทอร์เฟซประเภทเดียวกันในยูเนียน?


ฉันมีประเภทไม่กี่ประเภทที่สรุปไว้ดังนี้:

interface Person {
    name: string;
}
interface Core<T> {
    fnc: (arg: T) => void;
    args: T;
}
interface One extends Core<Person> {
    type: 'modifyPerson';
}
interface Two extends Core<Person & { age: number }> {
    type: 'modifyAgeingPerson';
}

ฉันจึงมีฟังก์ชันที่สามารถจัดการทั้งการแก้ไขสมบัติที่ใช้ร่วมกันของบุคคลหรือบุคคลที่มีอายุมากขึ้น - ดังนั้นมันจึงมีชนิดผสม ตัวอย่างดังนี้:

modifyPersonCharacteristics(person: One | Two) {
    person.fnc({ ...person.args, name: 'Steven' });
}

อย่างไรก็ตาม TypeScript ไม่ชอบสิ่งนี้เนื่องจากมีการซ้อนทับของประเภท - แต่ในกรณีนี้เนื่องจากมีการใช้ generic มันจะมีผลจริงหรือ? ไม่ว่าจะเป็น instance ของ One หรือ Two ก็สามารถรับ arguments ที่ส่งเข้าไปได้ทั้งคู่

มีวิธีใดบ้างที่จะทำให้ TypeScript มองภาพรวมของ generic ได้บ้าง?

หมายเหตุเพิ่มเติมคือ สิ่งต่อไปนี้สามารถทำได้ แต่ด้วยเหตุผลที่ชัดเจนฉันไม่อยากจะทำ

modifyPersonCharacteristics(person: One | Two) {
    if (person.type === 'modifyPerson') {
        person.fnc({ ...person.args, name: 'Steven' });
    } else {
        person.fnc({ ...person.args, name: 'Steven' });
    }
}

คำตอบ #1

ฉันคิดว่าปัญหาของคุณคือคุณกำหนดพารามิเตอร์ของ fnc อย่างแคบเกินไป สำหรับประเด็นของคุณเกี่ยวกับภาพรวมที่ใหญ่ขึ้น--ประเด็นคือ fnc ของคุณสามารถทำงานกับประเภทใดก็ได้ที่ขยาย (หรือเชื่อม) กับ Person ดังนั้นจึงเพียงแค่ต้องประกาศให้เป็นแบบนั้น เช่นนี้

interface Person {
    name: string;
}
interface Core<T> {
    fnc: (arg: Person) => void;  //This is the line that's changed.
    args: T;
}
interface One extends Core<Person> {
    type: 'modifyPerson';
}
interface Two extends Core<Person & { age: number }> {
    type: 'modifyAgeingPerson';
}

function modifyPersonCharacteristics(person: One | Two) {
    person.fnc({ ...person.args, name: 'Steven' });
}

สนามเด็กเล่นอยู่ที่นี่