JavaScript和TypeScript中的void

156 阅读2分钟

如果你来自传统的强类型语言,你可能熟悉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) // 👍

所以voidundefined 基本上是一样的。不过有一个小小的区别,这个区别很重要: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