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

การจำกัดประเภท - การใช้ TypeScript Type Predicates กับคุณสมบัติส่วนตัว


ฉันมีคลาสที่มีพร็อพเพอร์ตี้แบบส่วนตัวและเป็นตัวเลือก (private foo?: Foo) ภายในโค้ดส่วนตัวของคลาส ฉันจำเป็นต้องสามารถตรวจสอบว่าพร็อพเพอร์ตี้นี้มีอยู่หรือไม่ เพื่อที่ฉันจะสามารถจัดการกับความล้มเหลวเพียงครั้งเดียวในตอนต้นของเมธอด แล้วจากนั้นจัดการกับมันเหมือนไม่ใช่ตัวเลือกในส่วนที่เหลือของบล็อก

โค้ดด้านล่างทำงานได้อย่างราบรื่น ถ้า foo เป็นสาธารณะ อย่างไรก็ตาม เนื่องจากฉันต้องการให้ foo เป็นส่วนตัว มันจึงไม่ทำงาน แทนที่จะตรวจสอบว่า this สอดคล้องกับ FooBar & FooContainer ประเภทของ this กลับกลายเป็น never

พฤติกรรมนี้สมเหตุสมผลอย่างยิ่งสำหรับการใช้งานสาธารณะซึ่งฉันไม่ต้องการให้โค้ดภายนอกตรวจสอบการมีอยู่ของคุณสมบัติเฉพาะ แต่ฉันกำลังพยายามหาวิธีที่คล้ายกับ type-predicate ที่ฉันสามารถใช้แบบส่วนตัวภายในคลาสของฉันเพื่อทำให้คุณสมบัติที่กล่าวถึงไม่เป็นทางเลือก

interface Foo {
    bar: string;
}

interface FooContainer {
    foo: Foo;
}

class FooBar {
    private foo?: Foo;
    bar?: string

    constructor(foo?: Foo, bar?: string) {
        this.foo = foo;
        this.bar = bar;
    }

    private isFooContainer(): this is FooContainer {
        const { foo } = this;
        return typeof foo !== "undefined";
    }
    
    printFoo() {
        if (!this.isFooContainer()) throw new Error("There is no foo!!!!");
        // For the rest of this method `this.foo` should be typed as `Foo` rather than `Foo | undefined`
        console.log(this.foo.bar); // <--- No optional chaining (`this.foo?.bar`) required here.`
    }
}

คำตอบ #1

มันง่ายเหมือนกับการนำการตรวจสอบมาใส่ตรง ๆ เลยหรือเปล่า? ฉันสงสัยว่าฉันอาจพลาดวัตถุประสงค์ของการมีอินเทอร์เฟซและเงื่อนไข แต่สำหรับฉันมันดูโอเค...

interface Foo {
    bar: string;
}

class FooBar {
    #foo?:Foo;
    bar?:string;

    constructor(foo?:Foo, bar?:string) {
        this.#foo = foo;
        this.bar = bar;
    }
    
    printFoo() {
        if(typeof this.#foo === "undefined") throw new Error("There is no foo!!!!");
        console.log(this.#foo.bar); 
    }
}

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