Typescript 在私有属性上使用类型脚本类型谓词

Typescript 在私有属性上使用类型脚本类型谓词,typescript,narrowing,type-narrowing,Typescript,Narrowing,Type Narrowing,我有一个类,它有一个私有的可选属性(privatefoo?:foo)。在类的私有代码中,我需要能够验证该属性是否存在,以便我可以在方法开始时处理一次失败,然后在块的其余部分将其作为非可选处理 如果foo是公共的,下面的代码就像一个符咒。然而,因为我需要foo是私有的,所以它不起作用。与其验证此是否符合FooBar&FooContainer,不如将此的类型变为从不 这种行为对于公共使用完全有意义,因为我不想让外部代码验证私有属性的存在。然而,我正试图找到一种类似类型谓词的解决方案,我可以在类中私下

我有一个类,它有一个私有的可选属性(
privatefoo?:foo
)。在类的私有代码中,我需要能够验证该属性是否存在,以便我可以在方法开始时处理一次失败,然后在块的其余部分将其作为非可选处理

如果
foo
是公共的,下面的代码就像一个符咒。然而,因为我需要foo是私有的,所以它不起作用。与其验证
是否符合
FooBar&FooContainer
,不如将
的类型变为
从不

这种行为对于公共使用完全有意义,因为我不想让外部代码验证私有属性的存在。然而,我正试图找到一种类似类型谓词的解决方案,我可以在类中私下使用它来使所讨论的属性成为非可选的

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.`
    }
}
接口Foo{
酒吧:字符串;
}
接口容器{
富:富,;
}
福巴级{
私人foo?:foo;
条?:字符串
构造函数(foo?:foo,bar?:字符串){
this.foo=foo;
这个.bar=bar;
}
私有isFooContainer():这是FooContainer{
const{foo}=this;
返回foo的类型!=“未定义”;
}
printFoo(){
如果(!this.isFooContainer())抛出新错误(“没有foo!!!!”);
//对于此方法的其余部分,“this.foo”应键入为“foo”,而不是“foo”|未定义`

console.log(this.foo.bar);//是否像内联检查本身一样简单?我想知道我是否错过了拥有接口和谓词的目的,但这对我来说似乎很好

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); 
    }
}

技术上,这是一个我已经考虑过的替代方案。一次又一次地暴露原始的检查逻辑仍然是混乱的。考虑到大约有30种其他方法,就像<代码> PrimtFoo。类型谓词封装了检查逻辑。我随时都可以用TWIDI更新所有30种方法的基础检查逻辑。使用上面的解决方案,如果我想调整逻辑,我必须调整30个方法中的每一个。我倾向于检查和提取foo…
ts const getfoooorthrow=():foo=>{const{foo}=this;if(!foo)抛出新的fooounexpectedlyundefined();return foo;}//…const foo=this.getfoooorthrow();
从技术上讲,这是比较安全的。但是你必须小心并确保对原始this.foo:
ts this.foo={bar:1};const foo=this.getfoooorthrow();this.foo={bar:2};print(foo.bar);//1 print(this.foo?.bar)//2