根据打字稿void
is a 超类型 https://www.typescriptlang.org/docs/handbook/basic-types.html#void of the null
and undefined
类型。因此,具有 void 类型的函数可以返回null
or undefined
.
只是问题是当我尝试使用typeof val !== 'undefined'
and val !== undefined
。第二个失败了,但第一个正在工作。
根据文档typeof null
应该object
and typeof undefined
is undefined
(see here https://stackoverflow.com/a/49947791/2389232)
那么,第一种方法可以编译而第二种方法失败的原因是什么?这对我来说没有任何意义。
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)
See DEMO https://www.typescriptlang.org/play/#src=%0D%0Ainterface%20IFace%20%7B%0D%0A%20%20data%3A%20string%3B%0D%0A%7D%0D%0A%0D%0Afunction%20sample()%3A%20void%20%7C%20IFace%20%7B%20%2F%2F%20void%20could%20be%20null%20or%20undefined%0D%0A%20%20return%20null%3B%0D%0A%7D%0D%0A%0D%0Alet%20value%20%3D%20sample()%3B%0D%0A%0D%0Aif(%20value%20!%3D%3D%20undefined%20)%0D%0A%20%20%20%20console.log(value.data)%3B%20%2F%2F%20It%20fails%20because%20value%20could%20be%20null%0D%0A%0D%0Aif(%20typeof%20value%20!%3D%3D%20'undefined'%20)%0D%0A%20%20%20%20console.log(value.data)%3B%20%2F%2F%20Why%20is%20it%20working%3F%20typeof%20value%20could%20be%20object%20(because%20null)%0D%0A
它似乎typeof value !== 'undefined'
被解释为一个对象(因为typeof null
and typeof IFace
是对象)。但是空对象那里没有数据字段,所以它应该失败吗?
UPDATED根据TypeScript 文档 https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html with strictNullChecks
选项true
可以解决这个问题:
在严格的空检查模式下,空值和未定义值并不在每种类型的域中,并且只能分配给它们自己和任何(一个例外是未定义也可以分配给void)。因此,而 T 和 T | undefined 在常规类型检查模式下被视为同义(因为 undefined 被视为任何 T 的子类型),在严格类型检查模式下它们是不同的类型,并且只有 T | undefined 允许未定义的值。 T 与 T | 的关系也是如此。无效的.
但我不知道为什么typeof
正在与strictNullChecks
to false
。根据这个 TypeScript 问题 https://github.com/Microsoft/TypeScript/issues/29405#issuecomment-454085408原因是因为typeof
正在工作,似乎编译器没有特殊情况typeof
出于类型检查目的的表达式中。