TypeScript:void 返回类型转换为任何类型?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12761607/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
TypeScript: void return type converted to any type?
提问by Peter StJ
I seem to be not able to comprehend why the following code does not raise error:
我似乎无法理解为什么以下代码不会引发错误:
var rg: {(): void;}[] = [];
rg.push(function():string {return "";})
I clearly state that the type should be an array of functions that return void, however I push there a function that returns a stringand yet the compiler does not complain. If I change the definition of rgto
我明确指出该类型应该是一个返回的函数数组void,但是我推送了一个返回 a 的函数,string但编译器没有抱怨。如果我将定义更改rg为
var rg: {():number;}[] = [];
The compiler starts to complain.
编译器开始抱怨。
Is this a bug or is it how the void return type is supposed to work (i.e. anything goes if voidis used, basically making it the same as return type any)?
这是一个错误还是 void 返回类型应该如何工作(即,如果void使用任何东西,基本上使它与返回类型相同any)?
回答by Ryan Cavanaugh
This is by design (I'll explain why it's good design shortly). The spec says (in section 3.6.3, abridged for clarity):
这是设计使然(我将很快解释为什么它是好的设计)。规范说(在第 3.6.3 节中,为了清楚起见而删节):
A type S is assignable to a type T, and T is assignable from S, if one of the following is true...
S and T are object types and, for each member M in T, one of the following is true:
M is a call, construct or index signature and S contains a call, construct or index signature N where
- the result type of M is Void, or the result type of N is assignable to that of M.
类型 S 可分配给类型 T,并且 T 可从 S 分配,如果以下条件之一为真...
S 和 T 是对象类型,对于 T 中的每个成员 M,以下情况之一为真:
M 是调用、构造或索引签名,S 包含调用、构造或索引签名 N,其中
- M 的结果类型为 Void,或 N 的结果类型可分配给 M 的结果类型。
In this case, we're testing if () => stringis assignable to () => void. So either stringhas to be assignable to void(it isn't), or voidhas to be void(it is).
在这种情况下,我们正在测试是否() => string可分配给() => void。所以要么string必须可分配给void(它不是),要么void必须是void(它是)。
In effect, the rule here is you are allowed to throw away the return value, which is consistent with how e.g. C++ treats voidin template resolution.
实际上,这里的规则是您可以丢弃返回值,这与例如 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?
When we constrain the type of changeto be (widget) => void, we're making it so that you can pass decrementWidgetHeightas the second argument even though it has a return value, butstill making sure that when we write the body of applyToManyWidgets, we don't accidentally use the return value of changeanywhere.
当我们将 的类型限制change为 时(widget) => void,我们这样做是为了您可以将其decrementWidgetHeight作为第二个参数传递,即使它有返回值,但仍要确保在编写 的主体时applyToManyWidgets,我们不会意外地使用change任何地方的返回值。
Note that voidis still different than anybecause this is unallowed:
请注意,这void仍然不同于any因为这是不允许的:
function f() { }
var x = f(); // Disallowed, f() is of type 'void'
回答by Steven Ickman
That looks like a bug. You should open a new work itemfor the issue
这看起来像一个错误。您应该为问题打开一个新的工作项

