void
对于 TypeScript 中的其它基本类型如 number string boolean 都很好理解,void 的用法就有点特别。
我们最常见的就是在一个不返回任何值的函数中,它的返回类型会被推断为 void :
const f = () => {
console.log('return nothing')
}
const v = f(); // inferred v: void
简单地说: void 表示不返回任何东西。我们可以把 void 看作是 any 的相反类型,因为 any 表示可以任何类型值。
虽然它也是一个类型,但在 TS 中给一个变量显式定义 void 类型是没有任何意义的,这样的话我们只能给该变量赋值为 undefined 或者 null (关闭 —strictNullChecks 的情况下),正如我们通常也不会特意去定义一个变量为 undefined 。
let a: void = undefined; // no need.
a = null; // if --strictNullChecks disabled.
在 JavaScript 中,没有显式返回任何值的函数默认返回 undefined ,这样正好跟只有 undefined 才能赋值给 void 类型的规则契合。
使用 void 类型
前面说通常不会显式给一个变量定义 void 类型,在某些情况下手动指定 void 类型还是有用的,比如对于 this 值。
对于TypeScript 中的函数或者方法的 this ,它的默认类型都是 any ,从 TypeScript 2.0 开始,我们可以显式指定 this 的类型,它作为一个伪参数出现在函数参数列表的第一位:
function f(this:void) {
this.o = 0; // Property 'o' does not exist on type 'void'.
}
在一个全局定义的独立函数中,它的 this 值默认值是 global ,在这个函数内使用 this 是没有任何意义的,所以我们可以显式定义 this: void 表示这里不需要使用 this 。
来看一个更具体一点的例子:
// come from typescript release note.
interface UIElement {
addClickListener(onclick: (this: void, e: Event) => void): void;
}
class Handler {
info: string;
onClickBad(this: Handler, e: Event) {
// oops, used `this` here. using this callback would crash at runtime
this.info = e.message;
}
}
let h = new Handler();
uiElement.addClickListener(h.onClickBad); // error!
在上面的这里例子中,调用 addClickListener 方法的是 UIElement 的实例,它的 this 值指向的是该实例,而 onclick 方法作为一个回调函数传进来,会丢失它自身真正的 this ,所以在 onclick 的类型定义中显式把 this 定义为 void ,告诉使用者不能在传给 addClickListener 的回调函数中使用 this,否则会报错。