【问题标题】:Union types in TypeScript - can I achieve this?TypeScript 中的联合类型 - 我能做到这一点吗?
【发布时间】:2018-07-16 12:01:53
【问题描述】:

我想实现以下目标:

class MyClass {    
  boolProp: boolean;  
}

let a: string | MyClass;
a.boolProp = false; // error

最后一行抛出一个错误,因为这就是 typescript 的工作原理。

我可以在没有typeguards的情况下实现上述目标吗? 我只是想能够告诉编译器某个变量是 a 或 b 类型,所以它应该认为它是 both 类型属性和方法的“真正”联合,而不仅仅是常见的那些。

我对其他语言的此类行为很熟悉,在我看来,这似乎是对 typescript 的功能要求。

我错过了什么吗?

【问题讨论】:

    标签: typescript typescript-typings


    【解决方案1】:

    您希望补充类型联合,type intersection。

    class MyClass {    
      boolProp: boolean;  
    }
    
    let a: string & MyClass;
    a.boolProp = false; // no error
    

    类型联合声明变量是一种类型或另一种类型,因此您可以可靠访问的唯一属性是两者共有的属性。类型交集宣布一个变量满足两种类型约定,因此您可以访问属于其任一组件类型的属性——这正是您想要的。

    【讨论】:

    • 这就是我一直在寻找的!谢谢!奇怪的是,命名与它的自然含义相反(至少在我看来):“交叉”和“联合”可以被替换。此外,类型写作也相反。如果我输入 myVar: a |乙;我希望 myVar 的类型为 a OR b,这意味着访问这些类型的属性中的任何一个都不会受到伤害。但这只是在重复我自己......再次感谢!
    • @BoazRymland 我想谈谈一些事情。您说“我希望 myVar 的类型为 a OR b”。这确实是那个意思。但是你说如果类型安全是一个问题,那么“意味着访问这些类型属性中的任何一个都不会受到伤害”,那么我们在逻辑上不能保证访问a 的成员是安全的,因为myVar 实际上可能是输入b。我们只能保证a 和b 拥有的属性可以安全访问。
    • @BoazRymland 类型可以被视为符合该类型的所有可能值的集合。所以交集类型对应于这些集合的交集。如果这两种类型都是具有命名属性的对象类型,并且如果值属于这两种类型(属于交集类型),则该值必须具有两种类型的所有属性,因此对象类型的交集具有它们的属性的联合。所以从一侧看自然是“交叉”,从另一侧看是“联合”——这就是他们所说的二元性。
    • @Paarth 是的,我明白你的意思,我接受。这是一种我将不得不考虑更多甚至采用的思维方式。恕我直言,当我在我的代码中接受一个类型为 A 或 B 的变量时,我总是记得在编码时它可以是类型... A 或 B... :-) 。意思是,我考虑到这一点并且必须考虑到这一点。您的/TS 方法可以说是更安全或更严格,但它不符合我的思维方式。
    • @artem 感谢您的额外发言
    【解决方案2】:

    根据定义,联合类型仅包含 common properties:

    如果我们有一个联合类型的值,我们只能访问成员 对联合中的所有类型都是通用的

    在运行时,您需要检查特定值是 string 还是 MyClass 以了解 boolProp 是否是所述值的属性,这就是类型保护起作用的地方。

    如果在您的代码中您要为 string 实例创建一个 boolProp 属性,那么您最好执行以下操作:

    type MyString = string & { boolProp: boolean };
    

    那么你可以这样使用它:

    let a: MyString | MyClass;
    a.boolProp = false; // works
    

    这样您就可以区分具有boolProp 的字符串实例和不具有boolProp 的实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-09
      • 2011-09-15
      • 1970-01-01
      相关资源
      最近更新 更多