根据打字稿void
是null
和undefined
类型的supertype。因此,具有void类型的函数可以返回null
或undefined
。
问题只是当我尝试使用typeof val !== 'undefined'
和val !== undefined
进行编译时。第二个失败了,但是第一个正在工作。
根据文档typeof null
应为object
,typeof undefined
应为undefined
(see here)
那么,这是因为第一种方法正在编译而第二种方法却失败了的原因是什么?对我来说没有意义。
interface IFace {
data: string;
}
function sample(): void | IFace { // void could be null or undefined
return null;
}
let value = sample();
if( value !== undefined )
console.log(value.data); // It fails because value could be null
if( typeof value !== 'undefined' )
console.log(value.data); // Why is it working? typeof value could be object (because null)
似乎typeof value !== 'undefined'
被解释为对象(因为typeof null
和typeof IFace
是对象)。但是空对象那里没有数据字段,所以应该失败吗?
已更新
根据{{3}},并选择strictNullChecks
的{{1}}选项可以解决此问题:
在严格的null检查模式下,null和undefined值不在每种类型的域中,并且只能分配给它们自己和任何值(一个例外是undefined也可以分配给void)。因此,而T和T | undefined在常规类型检查模式下被视为同义词(因为undefined被视为任何T的子类型),在严格类型检查模式下它们是不同类型,只有T |未定义允许未定义的值。 T与T的关系也是如此。空。
但是我不知道为什么true
与typeof
到strictNullChecks
一起工作。根据{{3}},因为false
起作用的原因似乎是编译器在表达式中出于类型检查的目的没有对typeof
进行特殊情况。
答案 0 :(得分:0)
如文档中所述。
这里的联合类型可能会有些棘手,但是要习惯它需要一些直觉。如果值的类型为A | B,我们只能肯定地知道它具有A和B都具有的成员。在此示例中,Bird有一个名为fly的成员。我们无法确定变量类型为Bird |鱼有飞蝇的方法。如果变量在运行时确实是Fish,则调用pet.fly()将失败。
在您的示例中void没有属性'data'。因此以下内容无法识别:
if( value !== undefined )
console.log(value.data);
您还可以按以下方式对其进行更新以使其起作用:
if( (<IFace>value).data !== undefined )
console.log((<IFace>value).data);
然后图片中出现了称为Type Guard的内容。并且打字稿将typeof识别为类型保护之一。
这些typeof类型防护有两种不同的形式:typeof v ===“ typename”和typeof v!==“ typename”,其中“ typename”必须为“ number”,“ string”,“ boolean”,或“符号”。虽然TypeScript不会阻止您与其他字符串进行比较,但该语言不会将这些表达式识别为类型保护。
此处是link,以获取更多信息。