英文:
Type inference with union types in TypeScript
问题
我有一个类型C,它是A和B类型的联合。我有一个类型C的变量,在分配了B类型之后,似乎类型推断在B和C具有相同名称的属性时不起作用。
class A {
    prop1: string;
}
class B {
    prop1: string;
    prop2: string;
}
type C = A | B;
class test {
    thisIsC: C;
    constructor() {
        this.thisIsC = this.getTypeB(); //这不会使thisIsC被推断为B
        const b = this.getTypeB(); //这样可以正常工作
        const a = this.thisIsC;
    }
    getTypeB(): B {
        return new B();
    }
}
如果属性不发生冲突,问题就不会出现,类型推断会正常工作(例如):
class A {
    prop1: string;
}
class B {
    prop2: string;
    prop3: string;
}
type C = A | B;
class test {
    thisIsC: C;
    constructor() {
        this.thisIsC = this.getTypeB(); //这会使thisIsC被推断为B类型
        const a = this.thisIsC;
    }
    getTypeB(): B {
        return new B();
    }
}
我的问题是,如果我可以做一些改进类型推断的事情(与冲突的参数一起),只是告诉typescript在getTypeB()调用之后变量"thisIsC"是B类型。显然,“如果我们有一个具有联合类型的值,我们只能访问联合中所有类型的公共成员。”这对我来说有道理,但在我的代码中,“getTypeB()”明确返回B类型。我可以通过创建辅助变量或使用类型守卫进行手动类型断言来解决这个问题,但我想知道是否可以做些修改内部工作方式的事情。
Playground上的错误示例:
https://t.ly/iFZ0
提前感谢您的回答。
英文:
I have a type C which is the union of A and B types. I have a variable of type C and after assigning a B type it seems that the type infer is not working when B and C have one property with the same name.
class A {
    prop1: string;
}
class B {
    prop1: string;
    prop2: string;
}
type C = A | B;
class test {
    thisIsC: C;
    constructor() {
        this.thisIsC = this.getTypeB(); //This doesn't make thisIsC inferred to B
        const b = this.getTypeB(); //This works fine
        const a = this.thisIsC;
    }
    getTypeB(): B {
        return new B();
    }
}
If the properties don't collide, the problem doesn't appear and the type infer is done properly (for example):
class A {
    prop1: string;
}
class B {
    prop2: string;
    prop3: string;
}
type C = A | B;
class test {
    thisIsC: C;
    constructor() {
        this.thisIsC = this.getTypeB(); //This makes thisIsC be inferred to B type
        const a = this.thisIsC;
    }
    getTypeB(): B {
        return new B();
    }
}
My question is if I can do something to improve this type inference (with colliding parameters) just to tell typescript that the variable "thisIsC" is of type B after the getTypeB() call. Apparently "If we have a value that has a union type, we can only access members that are common to all types in the union." which makes sense to me, but in my code, "getTypeB()" returns explicitly a type B. I just can solve the problem creating an aux variable or doing a manual type assertion with a type guard but I want to know if I can do anything to modify how this internally works.
Playground with the error:
https://t.ly/iFZ0
Thanks in advance
答案1
得分: 1
Sure, here is the translated text:
> 我想知道我是否可以做任何修改内部工作方式的事情。
我建议对你的 A 和 B 类型进行 标记。
class A {
    prop1: string;
    tag: "A";
    constructor() {
        this.prop1 = "helloworld";
        this.tag = "A";
    }
}
class B {
    prop1: string;
    prop2: string;
    tag: "B";
    constructor() {
        this.prop1 = "helloworld";
        this.prop2 = "prop2";
        this.tag = "B";
    }
}
type C = A | B;
class test {
    thisIsC: C;
    constructor() {
        this.thisIsC = this.getTypeB();
        const b = this.thisIsC;
        b.prop2;
    }
    getTypeB(): B {
        return new B();
    }
}
在对它们进行标记之后,TypeScript 能够正确地推断类型。
英文:
> I want to know if I can do anything to modify how this internally works.
I would recommend tagging your A and B types.
class A {
    prop1: string;
    tag: "A";
    constructor() {
        this.prop1 = "helloworld";
        this.tag = "A"
    }
}
class B {
    prop1: string;
    prop2: string;
    tag: "B";
    constructor() {
        this.prop1 = "helloworld";
        this.prop2 = "prop2";
        this.tag = "B";
    }
}
type C = A | B;
class test {
    thisIsC: C;
    constructor() {
        this.thisIsC = this.getTypeB();
        const b = this.thisIsC;
        b.prop2;
    }
    getTypeB(): B {
        return new B();
    }
}
After tagging them typescript is able to properly infer the types.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论