void 在函数返回类型中有特殊含义,不是undefined 的别名。这样想是非常错误的。为什么?
void 的意图是函数的返回值不会被观察到。这与 将是 undefined 非常不同。有这种区别很重要,这样您就可以正确描述像forEach 这样的函数。让我们考虑一个独立版本的Array#forEach,在回调返回位置使用undefined 而不是void:
declare function forEach<T>(arr: T[], callback: (el: T) => undefined): void;
如果您尝试使用此功能:
let target: number[] = [];
forEach([1, 2, 3], el => target.push(el));
你会得到一个错误:
类型“数字”不能分配给类型“未定义”
这是一个正确的错误 - 你说你想要一个返回值 undefined 的函数,但你实际上提供了一个返回值 number 的函数,因为这是 Array#push 返回的值!
使用void 代替意味着forEach 承诺不使用返回值,因此可以使用返回任何值的回调来调用它
declare function forEach<T>(arr: T[], callback: (el: T) => void): void;
let target: number[] = [];
// OK
forEach([1, 2, 3], el => target.push(el));
为什么不直接使用 any 呢?如果您实际上是实现 forEach 的人,那么您真的不希望这样 - 让 any 浮动是一件很危险的事情,很容易破坏类型检查。
由此得出的结论是,如果您有某个返回类型为void 的函数表达式,您无法确定调用该函数的结果是undefined。 p>
同样,void 不是 undefined 的别名,void 类型的表达式可能有 any 值,而不仅仅是 undefined
在返回类型明确列为void 的函数body 中,TypeScript 将阻止您“意外”返回值,即使这不会造成类型系统违规。这有助于捕获重构中出现的错误:
// Old version
function fn(arr: number[]): void {
const arr1 = arr.map(x => {
return 3;
});
}
// New version
function fn(arr: number[]): void {
for (const x of arr) {
// Oops, meant to do something else
return 3;
};
}