【问题标题】:difference between `unknown` and `void``unknown` 和 `void` 之间的区别
【发布时间】:2021-05-17 07:06:12
【问题描述】:

根据this answer

使用void 代替意味着 forEach 承诺不使用返回值,因此可以使用返回任何值的回调来调用它

根据TypeScript 3.0 release notes

...unknownany 的类型安全对应物。任何东西都可以分配给unknown,但unknown 不能分配给除了它自己和any 之外的任何东西......

尽管我这么想,但从这些描述中我找不到这些类型之间的任何单一区别。

我还注意到,与unknown 不同,当void 用作函数参数的一种类型时,调用函数时可以省略该参数,即使它没有标记为可选:

declare const x: (a: void) => void

x()

playground

虽然这种行为在使用泛型代码时有时很有用,但看起来很奇怪。如果void 应该只用于返回类型,为什么它有这种特殊行为,不像其他类型?

【问题讨论】:

    标签: typescript typescript3.0


    【解决方案1】:

    经过与 Aluan Haddad 的长时间讨论,我的理解如下:

    unknown 是所有其他类型的超类型。在其他语言中,这主要是 void 类型 - 任何东西都可以分配给它,但它可以无用。

    void 是一种特殊类型。一般情况下,它只是undefined的超类型,没有其他类型,甚至null都没有。

    这使我们能够执行以下任何操作:

    const x: void = undefined;
    
    (): void => undefined;
    
    (): void => {};
    

    但阻止我们做任何事情:

    const x: void = null;
    
    const y: void = 5;
    
    (): void => 5;
    

    不过,与其他类型不同。 void 在输出位置(作为返回类型的一部分)使用时具有特殊行为:() => T 是任何 T() => void 的子类型,其中包括 undefinednull,当然还有void.

    这可以执行以下操作:

    const x: () => void = () => 5
    

    void 存在和被使用的原因似乎比实际更具有历史意义,因为它在 unknown 之前就已经存在,并且它与类型系统的交互方式不同于所有其他类型(这也会导致一些奇怪的诸如 Promise<number> 不是 Promise<void> 的子类型)。

    在这些类型之间做出决定的常用方法似乎是:

    • 它是我只为副作用调用的函数的返回类型吗?使用void
    • 它是否是我打算以某种方式使用但不能保证的类型(是否返回)?使用unknown

    【讨论】:

    【解决方案2】:

    简短的版本是使用返回 void 的函数,调用者必须忽略它。

    它与unknown 不同,因为unknown 没有明确表示“不要使用它”,它只是意味着它可以是任何东西。

    【讨论】:

      猜你喜欢
      • 2015-09-26
      • 2014-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多