为什么在Typescript的左侧部分允许使用void函数?

时间:2015-06-10 07:28:11

标签: typescript

考虑以下的Typescript代码:

var action = function action(): void {
    //do things
};

var res = action();

为什么TS编译器没问题?

3 个答案:

答案 0 :(得分:1)

  

为什么在Typescript的左侧部分允许使用void函数?

仅仅因为他们不被禁止。请注意,对于void变量,不能使用有用(坏)的东西,例如:

var action = function action(): void {};
var res = action();
res.foo; // Error 

答案 1 :(得分:1)

很有可能是因为,void是Typescript中的一种类型,它有一组可能的值,undefinednull,因此可以使用在左侧的任务中。

我发现允许在分配中使用键入void的值可能会导致严重错误。例如,如果一个函数返回一些有意义的函数被重构为返回void,那么编译时就不会出错。

对于参考Typescript 1.4语言规范有以下关于Void类型的说法:

  

Void类型[...]代表缺席   一个值,用作没有返回的函数的返回类型   值。 Void类型唯一可能的值为null和   未定义。 Void类型是Any类型的子类型和超类型   Null和Undefined类型,但Void无关   所有其他类型。
  注意:我们可能会考虑不允许声明   Void类型的变量,因为它们没有用处。然而,   因为Void被允许作为泛型类型的类型参数或   函数禁止Void属性或参数是不可行的。

答案 2 :(得分:0)

考虑以下代码:

// Generic function for perf measuring
function time<T>(f: () => T): T {
  var start = Date.now();
  var result = f();
  console.log('It took ' + (Date.now() - start) + ' to run');
  return f;
}

function doSomething(): void { }

time(doSomething);

如果我们将通用函数视为模板的特定于类型的实例化(注意:它们不是),result在调用void时属于time类型与doSomething。显然,当发生这种情况时,世界不会爆炸,因此拥有void类型的变量并不是必须被阻止的东西。

这是另一个例子:

declare function doNothing(): void;
declare function doOneThing(): void;
declare function doManyThings(): void;

function doSomething(x: number) {
    switch (x) {
        case 0:
            return doNothing();
        case 1:
            return doOneThing();
        default:
            return doManyThings();
    }
}

在这里,我们想要这样做,如果我们更改doSomething的返回类型,我们必须更新doNothing / doOneThing / doManyThings的返回类型。同样,这里的一般原则是void 正在四处移动而没有任何不良影响。这个例子是人为的 - 它改编自TypeScript编译器本身的一些代码。

让代码重构一下:

function doSomething(x: number) {
    if (x > 1) {
        return doManyThings();
    } else {
        // result: void!
        var result = x === 0 ? doNothing() : doOneThing();
        return result;
    }
}

为什么这种无害的重构会引入错误?重点是什么?如果我们尝试访问result的任何属性,那将是一个错误。如果我们不尝试访问result的任何属性,我们可能会做错任何事情并且不应该被打扰。