我似乎无法理解为什么以下代码不会引发错误:
var rg: {(): void;}[] = [];
rg.push(function():string {return "";})
我清楚地声明类型应该是返回void
的函数数组,但是我推送一个返回string
的函数但编译器没有抱怨。如果我将rg
的定义更改为
var rg: {():number;}[] = [];
编译器开始抱怨。
这是一个错误,还是void返回类型应该如何工作(即如果使用void
则会发生任何事情,基本上使它与返回类型any
相同)?
答案 0 :(得分:21)
这是设计的(我会解释为什么它很快就会成为好的设计)。规范说明(在第3.6.3节中,为清晰起见而删节):
类型S可分配给类型T,如果满足下列条件之一,则可从S分配T ...
S和T是对象类型,对于T中的每个成员M,以下之一为真:
M是一个调用,构造或索引签名,S包含一个调用,构造或索引签名N,其中
- M的结果类型为Void,或者N的结果类型可分配给M.
的结果类型
在这种情况下,我们正在测试() => string
是否可分配给() => void
。因此,string
必须可以分配给void
(不是),或者void
必须是void
(它是)。
实际上,此处的规则是您可以丢弃返回值,这与例如C ++在模板解析中处理void
。
function decrementWidgetHeight(w: Widget): number {
// ... returns the new height of the widget
}
function applyToManyWidgets(w: Widget[], change: (x: Widget) => void): void {
// for each widget in the array, apply 'change' to it
}
// Later...
applyToManyWidgets(widgetsToShorten, decrementWidgetHeight); // Should be allowed?
当我们将change
的类型约束为(widget) => void
时,我们正在制作它,以便您可以将decrementWidgetHeight
作为第二个参数传递,即使它具有返回值,< em>但是仍然确保在我们编写applyToManyWidgets
的正文时,我们不会在任何地方意外使用change
的返回值。
请注意void
仍然不同于any
,因为这是不允许的:
function f() { }
var x = f(); // Disallowed, f() is of type 'void'
答案 1 :(得分:0)
这看起来像个错误。您应该为问题打开new work item