2016-01-06 129 views
0

为什么returnObject导致编译TypeError returnObject2是不是?Typescript功能奇怪的空白|| &&行为

通常,void || something应返回something,而void && something应返回void

但是在打字稿中,情况恰恰相反。

var returnVoid = function(){}; 

var returnObject = function(){ //Typescript compilation TypeError. 
    //No best common type exists among return expressions. 
    if(Math.random() < 0.5) 
     return new Error(); 
    return returnVoid() || null; //always return null 
} 
var returnObject2 = function(){ //works 
    if(Math.random() < 0.5) 
     return new Error(); 
    return returnVoid() && null; //always return undefined 
} 

注意:类型错误发生在编译期间,而不是在运行时。


编辑:我做了另一个测试。 returnNum2应该不是() => number考虑(undefined || something) === something?注意:void 0的行为相同。

var returnNum = function(){ //() => number 
    return undefined || 0; 
} 

var returnVoid = function(){}; 

var returnNum2 = function(){ //() => void | number 
    return returnVoid() || 0; 
} 
+2

'空== void'! –

+0

不确定你的意思......'undefined'和'void'是''''和'&&'操作中的“false”值。 – RainingChain

+1

我不明白如何发布的代码演示任何东西。这些功能如何被调用?第一个将返回一个错误或null,而第二个返回错误或未定义。 – Pointy

回答

3

它已经指出的评论,但我想一般你只需要明白function(){}将返回undefined,已指定行为逻辑运算符。

对于undefined && somevalue,总是会返回undefined。对于undefined || somevalue,somevalue将被评估并返回。

下面是详细信息,一个很好的参考:http://www.javascriptkit.com/jsref/comparison_operators.shtml

编辑:问题不在于什么返回用于逻辑操作,但为什么打字稿给出编译error TS2354: No best common type exists among return expressions.

这确实看起来像一个错误,但在上下文中可能有意义。如果仅用returnVoid()的调用来替换逻辑运算符,则在两个函数中都会出现相同的错误。静态类型允许&&运营商完全短路键入,因为something && null永远不会评估类型,但something || null可能取决于something是什么。

与此相关,在打字稿中,您不能显式指定null或undefined作为函数的返回类型。

虽然我明白为什么会出现这种情况,但我同意这有点奇怪。这可能是值得与制作打字稿并提交错误的人进行核对。

+0

是的,根据该逻辑,Typescript TypeError应该发生在'returnObject2'中,而不是'returnObject'中。 – RainingChain

+0

@RainingChain我明白了,我错过了这个问题的基础。我已经更新了我的答案以反映这一点。 –

2

打字稿做形式undefined || Tvoid || T的不是特殊情况下表现为T因为)你不应该写代码(用逗号!)和b)它不是安全写这个代码,因为返回值反转意味着你不能保证只因为你有一个返回void的函数引用而产生一个falsy值。

考虑,如果你写了这样的代码:

type callback = (arg: any) => void; 

function doSomething(x: callback) { 
    return x(10) || 'Hello, world!'; 
} 

var x = []; 
var add = (arg: any) => x.push(arg); 
console.log(doSomething(add)); // Prints '1', not 'Hello, world!'