【问题标题】:Why is undefined assignable to void?为什么 undefined 可以分配给 void?
【发布时间】:2021-12-12 03:26:45
【问题描述】:

在 typescript 的文档中写道:“一个例外是 undefined 也可分配给 void”。

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#--strictnullchecks

在严格的 null 检查模式下,null 和 undefined 值不在每种类型的域中,并且只能分配给它们自己和任何类型(一个例外是 undefined 也可以分配给 void)。所以,而 T 和 T | undefined 在常规类型检查模式下被认为是同义词(因为 undefined 被认为是任何 T 的子类型),它们在严格类型检查模式下是不同的类型,并且只有 T | undefined 允许未定义的值。 T 与 T 的关系也是如此 |空。

为什么这个例外是针对 void 的?

This 不是答案。请不要提供

【问题讨论】:

标签: typescript


【解决方案1】:

voidundefined 之间的关系有点混乱,因为它们的使用方式有一些相互不一致的地方。大致上,void 是指不返回有意义值的函数的返回类型。但是,当您开始将其分开时,它会变得很粘。


void-returning 函数的调用者的角度来看,这意味着用返回值做很多事情本质上是一个错误:

declare let voidReturn: () => void;

let v = voidReturn();
v.foo; // Property 'foo' does not exist on type 'void'
v + 2; // Operator '+' cannot be applied to types 'void' and 'number

由于调用者本质上承诺不检查 void-returning 函数的返回值,因此在其位置分配任何函数都是安全的,无论它是否返回值:

voidReturn = () => 123; // okay

请参阅the handbook documentation about returning void 了解允许这样做的原因。

无论如何,从这个角度来看,你真的不应该看到undefined 特别可分配给void。您不能真正使用void 返回值,就好像它是undefined(因为它很可能是123,如您所见),并且类型检查函数类型在某种意义上将几乎任何东西都视为可分配给void () => T 可分配给所有T() => void

void-returning 函数的调用者的角度来看,好像void 就像the unknown type。但是voidunknown 早了很多。


另一方面,从void-returning 函数的实现者的角度来看,编译器认为返回任何定义的值都是错误的:

function voidReturn2(): void {
  return 123; // error!
  // Type 'number' is not assignable to type 'void'.(2322)
}

这与voidReturn = () => 123 分配的函数表达式几乎相同,但是这个被认为是错误的。是的,这在技术上是不一致的。在需要void-returning 函数的地方使用现有的事物返回回调函数很有用,并且一直在发生,如上述手册文档中所述。但是,直接返回一个定义的值,其中应该是 void 值,它的用处不大,而且更多地表明了错误。

无论如何,这意味着你在实现void返回函数时不应该返回任何东西:

function voidReturn3(): void { } // okay

没有返回语句的函数等效于仅以return; 结尾的函数。所以编译器可能也应该接受这一点,它确实:

function voidReturn4(): void {
  return;
} // okay

return 之后没有指定值的函数等效于返回undefined 的函数。所以编译器也应该接受这一点,它确实:

function voidReturn5(): void {
  return undefined;
} // okay

就是为什么undefined可以分配给void。当您有一个应该是 void 类型的表达式时,唯一可接受的值是 undefined


当然,它并不是真正一致的,并且会导致一些可能不受欢迎的奇怪行为。 void 返回函数的调用者应该忽略它们的返回值。但他们不必这样做,然后他们可能会有一个void 类型的变量在附近徘徊。您可以将undefined 分配给它,但不能分配123

let w = voidReturn();
w = 123; // error
w = undefined; // okay, but that's weird

哦,好吧。

您还可以查看 microsoft/TypeScript#25481 和其他有关 void 奇怪行为的 Stack Overflow 问题,例如 Why does TypeScript have both `void` and `undefined`?why is return type `null` (or any other type) assignable to return type `void`?Typescript: void union type

Playground link to code

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-03
    • 2018-09-29
    • 2015-07-31
    • 1970-01-01
    • 2020-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多