Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 何时';联合类型';上不存在Typescript属性;无法使用变量进行计算_Javascript_Typescript_Types_Union Types - Fatal编程技术网

Javascript 何时';联合类型';上不存在Typescript属性;无法使用变量进行计算

Javascript 何时';联合类型';上不存在Typescript属性;无法使用变量进行计算,javascript,typescript,types,union-types,Javascript,Typescript,Types,Union Types,这是我们的后续问题 提供的方法是使用。太棒了!下面是一个例子: type Obj1={message:string} 类型Obj2={text:string} 常量getText=(obj:Obj1 | Obj2):字符串=>{ 如果(obj中的“消息”){ 返回obj.message } 返回obj.text } 但是,当我尝试使用变量对其求值时,会出现相同的错误: const getText=(obj:Obj1 | Obj2):string=>{ let property=“消息” if(

这是我们的后续问题

提供的方法是使用。太棒了!下面是一个例子:

type Obj1={message:string}
类型Obj2={text:string}
常量getText=(obj:Obj1 | Obj2):字符串=>{
如果(obj中的“消息”){
返回obj.message
}
返回obj.text
}
但是,当我尝试使用变量对其求值时,会出现相同的错误:

const getText=(obj:Obj1 | Obj2):string=>{
let property=“消息”
if(obj中的属性){
返回obj.message
}
返回obj.text
}

我是不是遗漏了一些非常明显的东西?

Typescript不相信这样的条件实际上会在键是变量(而不是文本)时缩小类型。您可以这样说,因为当您将鼠标悬停在条件分支中的obj上时,它会报告一种类型的
Obj1 | Obj2

看起来编译器应该能够解决这个问题,并且知道它是安全的,但是typescript编译器并不完美。但它被设计成悲观主义的一方,因为过度报告问题比允许问题滑入生产代码的危险要小得多

这种情况似乎是一个很大的限制。但在实践中,它不会出现太多。您的代码要求
消息
属性在该条件中可用。使用变量来测试这一点没有任何意义,因为为了使类型安全代码只能是
属性的一个值。因此,您也可以在测试中使用文本字符串


但是,如果您对此进行了大量测试,并且希望避免反复键入sam文本,则可以使用一个简单的可重用方法来执行此操作:

function isObj1(obj: Obj1 | Obj2): obj is Obj1 {
    return 'message' in obj
}

const getText = (obj: Obj1 | Obj2): string => {
   if (isObj1(obj)) {
      return obj.message
   }

   return obj.text
}

如果使用let,它将不起作用,因为左侧不是字符串文字类型(请参阅),但出于某种原因,它也不适用于常量。是的,我注意到了这一点。它似乎对任何声明都不起作用。这真的很有帮助。非常感谢。我们面临的问题是,union包含29个对象,其属性差异不到100个。不逐案处理是很好的,但这似乎是唯一的途径。听起来很有趣。从这个例子到你在这里的评论很难搭建一座桥梁,但我想,无论你在这里想做什么,都有一个更好的方法。比如你有没有想过使用一个你可以拥有的公共财产?这也是个好主意!我可以写一个更详尽的例子与大家分享。这很棘手,因为对象实际上是使用api数据动态创建的类型化类(对象构造函数)。属性也是从API动态创建的。然后使用上述方法指定属性。