2017-06-09 15 views
4

可达有一些打字稿代码看起来基本上像这样我如何指示的路径是在TypeScipt

if(...) 
    result = $(document.createElement("div")) ; 
} else if(...) { 
    result = $(document.createElement("div")) ; 
} else { 
    assert.unreachable("Unknown label in buildHTML.") ; 
} 
result.attr("data-childNumber", childNumber.toString()) ; 

assert.unreachable返回类型是never

最后一行显示“变量结果”在分配前使用时出错。

在我看来,来自assert.unreachablenever结果应该告诉编译器,else部分中没有路径。

我知道我可以通过在else的末尾添加throw null;来抑制错误,但这看起来不雅观。

unreachable的定义中出现类似的问题。它看起来像这样

export function unreachable(message? : string) : never { 
    if(message===undefined) message = "Unreachable code reached." ; 
    else message = "Unreachable code reached: "+message ; 
    raiseTheAlarm(message) ; 
} 

其中raiseTheAlarm结果类型为never。在这种情况下,我得到一个错误“一个函数返回'永不'不能达到终点。”

我修正了这个问题,在调用raiseTheAlarm之前加了一个return关键字。这看起来有点奇怪。 (当然throw null;通话后也将工作。)

有没有更好的方式告诉编译器,代码中的一个点不可达?

+0

tsc编译器版本为2.3.4 –

+0

对'assert.unreachable' *的调用会阻止后续代码的执行,因为对'assert.unreachable'函数的调用永远不会返回。 –

+0

颜色我教育了'永不'类型。我完全错过了这个功能。对困惑感到抱歉。 – Silvermind

回答

1

在我看来,从assert.unreachable应该不会导致 告诉编译器,从else部分没有路径。

它运作的另一种方式。当编译器检测到某个路径不可访问时,它会为该路径中引用的变量推断never类型(如果可以)。您可以使用它来强制您的代码处理枚举或联合类型的所有可能值,如解释here所述。

但是,编译器不会使用某些路径无法访问的信息,因为它在初始化之前检查变量没有被使用。解决方案很简单 - 您可以将never值分配给不可达路径中的变量。正如上面回答中所解释的那样,never已被分配给专门用于此目的的任何其他类型。

if(...) 
    result = $(document.createElement("div")) ; 
} else if(...) { 
    result = $(document.createElement("div")) ; 
} else { 
    result = assert.unreachable("Unknown label in buildHTML.") ; 
} 
result.attr("data-childNumber", childNumber.toString()) ; 

一个问题,您unreachable功能被固定以同样的方式 - 它应该有

return raiseTheAlarm(message) ; 

的最后一条语句。

+0

很棒的回答。我有一个狡辩。你说“但是,编译器不会使用某些路径无法访问的信息,因为它在初始化之前检查变量没有被使用。”但是添加'throw null;'来抑制错误的事实表明编译器有时会这样做。 –

+1

添加'throw'或'return'可以明确地告诉编译器,在使用之前,不会有'result'未赋值的路径。一个可能的解释是[无法访问的代码分析是完全独立于分析之前检测使用的分析](https://github.com/Microsoft/TypeScript/issues/5207#issuecomment-147469302)他们可能应该在github上有一个问题那。 – artem

1

至少有三个选项

(一)

else { 
    return assert.unreachable("Unknown label in buildHTML.") ; 
} 

(B)(来自@阿尔乔姆的答案)

else { 
    result = assert.unreachable("Unknown label in buildHTML.") ; 
} 

(C)

else { 
    assert.unreachable("Unknown label in buildHTML.") ; 
    throw null ; 
} 

我选择了(a)。

相关问题