TypeScript:void返回类型转换为任何类型?

时间:2012-10-06 16:34:05

标签: typescript

我似乎无法理解为什么以下代码不会引发错误:

var rg: {(): void;}[] = [];
rg.push(function():string {return "";})

我清楚地声明类型应该是返回void的函数数组,但是我推送一个返回string的函数但编译器没有抱怨。如果我将rg的定义更改为

var rg: {():number;}[] = [];

编译器开始抱怨。

这是一个错误,还是void返回类型应该如何工作(即如果使用void则会发生任何事情,基本上使它与返回类型any相同)?

2 个答案:

答案 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