TypeScript:void 返回类型转换为任何类型? [英] TypeScript: void return type converted to any type?

查看:27
本文介绍了TypeScript:void 返回类型转换为任何类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I seem to be not able to comprehend why the following code does not raise error:

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

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

I clearly state that the type should be an array of functions that return void, however I push there a function that returns a string and yet the compiler does not complain. If I change the definition of rg to

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

编译器开始抱怨.

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

Is this a bug or is it how the void return type is supposed to work (i.e. anything goes if void is used, basically making it the same as return type any)?

推荐答案

这是设计使然(稍后我将解释为什么它是好的设计).规范说(在第 3.6.3 节中,为了清楚起见而删节):

This is by design (I'll explain why it's good design shortly). The spec says (in section 3.6.3, abridged for clarity):

类型 S 可分配给类型 T,并且 T 可从 S 分配,如果以下条件之一为真...

A type S is assignable to a type T, and T is assignable from S, if one of the following is true...

  • S 和 T 是对象类型,对于 T 中的每个成员 M,下列情况之一为真:

  • S and T are object types and, for each member M in T, one of the following is true:

  • M 是调用、构造或索引签名,S 包含调用、构造或索引签名 N,其中

  • M is a call, construct or index signature and S contains a call, construct or index signature N where

  • M 的结果类型为 Void,或者 N 的结果类型可赋值给 M 的结果类型.

在这种情况下,我们正在测试 () =>string 可分配给 () =>无效.所以要么 string 必须可以分配给 void(它不是),或者 void 必须是 void(是).

In this case, we're testing if () => string is assignable to () => void. So either string has to be assignable to void (it isn't), or void has to be void (it is).

实际上,这里的规则是你可以丢弃返回值,这与例如C++ 在模板解析中处理 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 void in template resolution.

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 作为第二个参数传递,即使它有返回值,但是仍然确保当我们写applyToManyWidgets的body,我们不会不小心在任何地方使用change的返回值.

When we constrain the type of change to be (widget) => void, we're making it so that you can pass decrementWidgetHeight as the second argument even though it has a return value, but still making sure that when we write the body of applyToManyWidgets, we don't accidentally use the return value of change anywhere.

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

Note that void is still different than any because this is unallowed:

function f() { }
var x = f(); // Disallowed, f() is of type 'void'

这篇关于TypeScript:void 返回类型转换为任何类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆