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

Pet*_*StJ 19 typescript

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

var rg: {(): void;}[] = [];
rg.push(function():string {return "";})
Run Code Online (Sandbox Code Playgroud)

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

var rg: {():number;}[] = [];
Run Code Online (Sandbox Code Playgroud)

编译器开始抱怨.

这是一个错误,或者它是如何工作的void返回类型(即如果void使用任何东西,基本上使它与返回类型相同any)?

Rya*_*ugh 22

这是设计(我会解释为什么它很快就会成为好的设计).规范说明(在第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?
Run Code Online (Sandbox Code Playgroud)

当我们限制的类型change(widget) => void,我们正在做的,这样就可以通过decrementWidgetHeight为即使它有一个返回值的第二个参数,仍确保当我们写的身体applyToManyWidgets,我们不小心使用change任何地方的返回值.

请注意,这void仍然不同,any因为这是不允许的:

function f() { }
var x = f(); // Disallowed, f() is of type 'void'
Run Code Online (Sandbox Code Playgroud)

  • 规范还说"void只与Undefined,Null和Any类型相关",所以我不确定规范是否一致.绝对出乎意料. (2认同)