考虑以下的Typescript代码:
var action = function action(): void {
//do things
};
var res = action();
为什么TS编译器没问题?
答案 0 :(得分:1)
为什么在Typescript的左侧部分允许使用void函数?
仅仅因为他们不被禁止。请注意,对于void变量,不能使用有用(坏)的东西,例如:
var action = function action(): void {};
var res = action();
res.foo; // Error
答案 1 :(得分:1)
很有可能是因为,void
是Typescript中的一种类型,它有一组可能的值,undefined
和null
,因此可以使用在左侧的任务中。
我发现允许在分配中使用键入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
的任何属性,我们可能会做错任何事情并且不应该被打扰。