微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

`unknown` 和 `void` 之间的区别

如何解决`unknown` 和 `void` 之间的区别

根据this answer

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

根据TypeScript 3.0 release notes

... unkNownany 的类型安全对应物。任何东西都可以分配给 unkNown,但 unkNown 不能分配给任何东西,除了它本身和 any ...

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

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

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

x()

playground

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

解决方法

经过与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 是任何 () => voidT 的子类型,其中包括 {{ 1}}、undefined,当然还有 null

这可以执行以下操作:

void

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

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

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

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

它是不同的 $ time ./random_perf ./random_perf 0.03s user 0.00s system 98% cpu 0.027 total ./random_perf -------------------------------------------------------------------------------- Ir -------------------------------------------------------------------------------- 147,608,621 PROGRAM TOTALS -------------------------------------------------------------------------------- Ir file:function -------------------------------------------------------------------------------- 106,311,924 /usr/lib/llvm-10/bin/../include/c++/v1/random:double std::__1::normal_distribution<double>::operator()<std::__1::mersenne_twister_engine<unsigned long,64ul,312ul,156ul,31ul,13043109905998158313ul,29ul,6148914691236517205ul,17ul,8202884508482404352ul,37ul,18444473444759240704ul,43ul,6364136223846793005ul> >(std::__1::mersenne_twister_engine<unsigned long,6364136223846793005ul>&,std::__1::normal_distribution<double>::param_type const&) [/home/xxx/EffectiveCpp/bin/random_perf] 22,905,902 /build/glibc-eX1tMB/glibc-2.31/math/../sysdeps/ieee754/dbl-64/e_log.c:__ieee754_log_fma [/usr/lib/x86_64-linux-gnu/libm-2.31.so] 6,000,007 /usr/lib/llvm-10/bin/../include/c++/v1/vector:main 3,003,122 /usr/lib/llvm-10/bin/../include/c++/v1/random:main 3,016 /home/xxx/EffectiveCpp/src/random_perf.cpp:main [/home/xxx/EffectiveCpp/bin/random_perf] 2,500,000 /build/glibc-eX1tMB/glibc-2.31/math/./w_log_template.c:log@@GLIBC_2.29 [/usr/lib/x86_64-linux-gnu/libm-2.31.so] 1,002 /usr/lib/llvm-10/bin/../include/c++/v1/memory:main 1,000 ???:0x000000000494b2f0 [???] 507,749 /build/glibc-eX1tMB/glibc-2.31/elf/dl-lookup.c:_dl_lookup_symbol_x [/usr/lib/x86_64-linux-gnu/ld-2.31.so] 因为 unknown 并没有明确表示“不要使用这个”,它只是表示它可以是任何东西。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。