【问题标题】:TypeScript: Why can't I access a property on a Union Type which is only defined on one object?TypeScript:为什么我不能访问仅在一个对象上定义的联合类型的属性?
【发布时间】:2021-02-06 04:42:05
【问题描述】:

我想要一个具有属性a 的对象,它是一个数字,或者一个具有属性b 的对象,它是一个字符串。在纯 JavaScript 中,如果另一个对象已通过,变量 test 将是一个数字或未定义。为什么这是 TypeScript 中的错误?或者有没有办法在没有类型保护的情况下做到这一点?

function t(aOrB: {a:number} | {b:string}){
    const test: number | undefined = aOrB.a
}

https://www.typescriptlang.org/play?#code/FAMwrgdgxgLglgewgAhgCgIYHkBOAhALmQG8MCIwBbAIwFMcBfZAHxOoIGcYc4IBzBgEpiwZGORQkXVLS5EKNei2SQAJrRC9aq5AF5k2fADoMwBsCA

【问题讨论】:

  • 我不明白这个问题。拥有静态类型系统的全部要点是不必在运行时进行这些类型的检查。你的问题就像问如何在你的喷气式飞机上安装一个支柱。
  • 如果我写const oops = {a: "hello", b: "goodbye"},我可以打电话给t(oops)with no error in TypeScript。这就是假设aOrB.anumber | undefined 的问题。最好将aOrB 设为{a: number, b?: undefined} | {a?: undefined, b: string} 类型。
  • @jcalz 这是我想要实现的目标,但没有样板:) 我认为它仍然是完全静态类型的(就像你所做的那样),但是没有所有这些额外的东西会更好(这就是JavaScript 默认工作)
  • 您能详细说明一下吗? TypeScript “没有所有这些额外的东西”只是 JavaScript。如果你想让 TypeScript 知道读取aOrB.a 会产生一个number | undefined 类型的值,那么你需要以某种方式告诉编译器。 TypeScript 中的对象类型不是exact,原因与类/接口层次结构有关,因此它不假定{a: number} | {b: string} 将具有number | undefined 类型的a 属性,因为@987654340 类型的值@ 可能有一些未知的a 属性。
  • 例如,this 是否适合您,您说aOrB: ExclusifyUnion<{a:number} | {b:string}>ExclusifyUnion 是一种实用程序类型,可以自动将“开放”联合变为“封闭”联合?还是您想保留{a: number} | {b: string} 并使用其他形式的type guard

标签: javascript typescript union-types


【解决方案1】:

您需要在返回之前检查if ('a' in aOrB)if ('b' in aOrB)

【讨论】:

    【解决方案2】:

    你可以像这样使用typeOf

    function t(aOrB:any){
    const test =((typeof(aOrB) == "object")?aOrB.a:aOrB);
    
    console.log(test);
    }
    t({a:123});
    t(123)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-28
      • 1970-01-01
      • 1970-01-01
      • 2020-09-27
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多