如果你来自传统的强类型语言,你可能熟悉void
的概念。一个类型告诉你函数和方法在被调用时不返回任何东西。
void
它在JavaScript中作为一个操作符存在,在TypeScript中作为一个原始类型存在。而在这两个世界中, 的工作方式与大多数人的习惯有一点不同。void
JavaScript中的void#
void
在JavaScript中是一个运算符,它评估它旁边的表达式。无论哪个表达式被评估, 总是返回 。void
undefined
let i = void 2; // i === undefined
为什么我们会需要这样的东西呢?首先,在早期,人们能够覆盖undefined
,给它一个实际的值。void
总是返回真正的undefined。
第二,这是一种调用立即调用的函数的好方法。
void function() {
console.log('What')
}()
所有这些都不会污染全局命名空间。
void function aRecursion(i) {
if(i > 0) {
console.log(i--)
aRecursion(i)
}
}(3)
console.log(typeof aRecursion) // undefined
因为void
总是返回undefined
,而void
总是评估它旁边的表达式,所以你有一个非常简洁的方法来从一个函数返回而不返回一个值,但仍然调用一个回调,例如。
// returning something else than undefined would crash the app
function middleware(nextCallback) {
if(conditionApplies()) {
return void nextCallback();
}
}
这给我带来了void
的最重要的用例。它是你的应用程序的一个安全门。当你的函数总是应该返回undefined
,你可以确保总是这样的。
button.onclick = () => void doSomething();
TypeScript中的void#
void
在TypeScript中是 的一个子类型。JavaScript中的函数总是返回一些东西。要么是一个值,要么是 。undefined
undefined
function iHaveNoReturnValue(i) {
console.log(i)
} // returns undefined
由于没有返回值的函数总是返回undefined
,而void
,在JavaScript中总是返回未定义的,TypeScript中的void
是一个合适的类型,用于告诉开发者这个函数返回undefined
。
declare function iHaveNoReturnValue(i: number): void
void
作为类型也可以用于参数和所有其他声明。唯一可以传递的值是 。undefined
declare function iTakeNoParameters(x: void): void
iTakeNoParameters() // 👍
iTakeNoParameters(undefined) // 👍
iTakeNoParameters(void 2) // 👍
所以void
和undefined
基本上是一样的。不过有一个小小的区别,这个区别很重要:void
作为返回类型可以用不同的类型代替,以允许高级回调模式。
function doSomething(callback: () => void) {
// at this position, callback always returns undefined
let c = callback()
//c is also of type undefiend
}
// this function returns a number
function aNumberCallback(): number {
return 2;
}
// works 👍 type safety is ensured in doSometing
doSomething(aNumberCallback)
这是人们所期望的行为,在JavaScript应用程序中经常使用。请在我的其他文章中阅读更多关于这种叫做可替换性的模式。
如果你想确保传递只返回undefined
(如 "无")的函数,一定要调整你的回调方法签名。
- function doSomething(callback: () => void) {
+ function doSomething(callback: () => undefined) { /* ... */ }
function aNumberCallback(): number { return 2; }
// 💥 types don't match
doSomething(aNumberCallback)
你可能在大多数时候都能用void
。