为什么 ts-toolbelt 库使用“Oextendsunknown”表达式

2024-04-25

我正在研究 ts-toolbelt 库的源代码。 而我也经常遇到这样的表情O extends unknown。在我看来,它没有添加任何功能。

所以我想知道,它是做什么用的?

/**
 * @hidden
 */
export type _UnionOf<O extends object> =
    O[keyof O]

/**
 * Transform an [[Object]] into an [[Union]]
 * @param O to transform
 * @returns [[Any]]
 * @example
 * ```ts
 * ```
 */
export type UnionOf<O extends object> =
    O extends unknown
    ? _UnionOf<O>
    : never

由于某种原因,而不是导出_UnionOf类型,它前面是表达式O extends unknown


想必图书馆作者决定UnionOf<A | B | C>应该产生相同的结果UnionOf<A> | UnionOf<B> | UnionOf<C>,以及定义_UnionOf没有那样做。这O extends unknown ? ... : nevercheck 看起来似乎什么也没做,却导致了这种情况的发生。

表达式看起来什么也没做,但实际上分布在联合中,当T是泛型类型参数:

  • T extends unknown ? ... : never
  • T extends any ? ... : never
  • T extends T ? ... : never

If T is a 类型参数,如在generic https://www.typescriptlang.org/docs/handbook/2/generics.html功能function foo<T>(/*...*/): void或通用接口interface Foo<T> {/*...*/},然后是一种形式T extends XXX ? YYY : ZZZ is a 分配性的条件类型 https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types.

It 分发条件检查unions https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types in T. When T指定了某种特定类型,编译器将该类型拆分为其联合成员,评估每个此类成员的检查,然后将结果连接回新的联合。因此,如果F<T>分配给各个工会,然后F<A | B | C>将与以下相同F<A> | F<B> | F<C>.


并非所有类型函数都可以跨联合分配。例如,the keyof操作员 https://www.typescriptlang.org/docs/handbook/2/keyof-types.html#the-keyof-type-operator不会将输入的并集转换为输出的并集:

type KeyofA = keyof {a: string}; // "a"
type KeyofB = keyof {b: number}; // "b"
type KeyofAorB = keyof ({ a: string } | { b: number }); // never

相似地,_UnionOf不跨工会分配(与它使用的事实有关)keyof在其定义中):

type Oops = _UnionOf<{ a: string } | { b: number }>
// never

如果你有一个类型函数not工会和你的分配want确实如此,您可以将其包装在分布式条件类型中:

type DistribKeyof<T> = T extends unknown ? keyof T : never;

type UnionKeyofAorB = DistribKeyof<{ a: string } | { b: number }>; // "a" | "b"

因此UnionOf is跨工会分配:

type Correct = UnionOf<{ a: string } | { b: number }>
// string | number

Playground 代码链接 https://www.typescriptlang.org/play?#code/C4TwDgpgBA0hIHsBmBBKBeKBreyoG8oBDALigGdgAnASwDsBzKAXwG4oB6DqAIiJ4BQoSLFxIAQhmxiCUAEZk6AVwC2ciFRbsuvOYOHQ4iVAiqTMOY1AAUhUhWr0mzKAB9ZCqMrUaWASm1uOggANw0BIXBoABEaSlo5I2QAHgAVAD4pVKgIAA9gCDoAE3IoJTosOgQAdzooAH5pK2zFUI1WCIMoAFU6GgQ6JJMzKVj4mkSxZLsyccYWNw9FVXVNZnTA3n5Fnj0IjgAqA4EoA6gAAQALGiKiwpODjgE8sFNgKC6AfV7+ugB5JDJP45fKFEpQBByABWEAAxsBMugTlAUX8ANqWPB-AC6+yODygqSoRDo5CQphUxDqaLRf2hcOA2OxUHowAQVKgNJ+AyZBPOYCIxMpwLZH2JpPJVBUfKoEGASiopM5aJQdBAvNOFzyRBUYAANhACQADE3AcjGk0PJ4vN4fKI9PoDAFAkEFYqlSEw+GI5Go11g0rlSo1Oi+hpQb6O-6Av7pMOtMJUCKREQAYVMsvhUm50emxFmjnmLnchE83lWLDjOjmTHc5fCKegfwQYFKmEjv2dMwctCLi1Lyx8ayrQTaVCAA

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 ts-toolbelt 库使用“Oextendsunknown”表达式 的相关文章

随机推荐

  • 如何使用 PowerShell 递归合并/“展平”文件夹结构

    我正在寻求帮助来重组许多子文件夹中的大量文件 示例来源 folderX aaa txt bbb txt folderY ccc txt folderZ ddd txt eee txt 理想结果 folderX aaa txt folderX
  • 自上一步以来进程或线程已更改

    我正在 Visual Studio 上调试一些代码 此代码属于我创建的自定义会话提供程序 我正在 Web 应用程序启动时对其进行调试 它开始初始化我的提供程序 并且在该函数上我有一个第一次成功命中的断点 但是 同一断点再次被击中 但它有一个
  • 带有自定义离线页面的 Angular PWA

    在 Angular 8 应用程序中 我想添加一个自定义离线页面 只是一个简单的 html 文件 我已将我的应用程序设置为 PWA 使用 angular pwa并配置了一切 以便它至少在在线时顺利工作 然而 我很难为 PWA 用户提供更新 因
  • unsafePerformIO 和 FFI 库初始化

    我正在为 C 中的库创建一个 FFI 模块 该模块希望在执行其他操作之前调用一个一次性 不可重入的函数 这个调用是幂等的 但是有状态的 所以我可以在每个 Haskell 调用中调用它 但它很慢 并且由于不可重入 可能会导致冲突 那么现在是使
  • 允许用户在 Android 应用程序中插入图像

    我的问题是 如何创建 imageButton 允许用户从手机上传图像并将其作为图片配置文件插入应用程序中 例如 像 Whatsapp 一样 它允许用户从手机中选择图像并将其设置为图片配置文件 Thanks 我的 XML 文件
  • 为什么 Func 与 Func> 不明确?

    这个问题让我很困惑 所以我想我会在这里问 希望 C 大师可以向我解释一下 为什么这段代码会产生错误 class Program static void Main string args Foo X the error is on this
  • Laravel 5.3 存储和读取文件目录

    目前正在尝试处理文件 但很难弄清楚将它们放在哪里以及如何在列表中读回它们 我尝试过将一些测试文件放入 files array dir opendir asset files open the cwd also do an err check
  • 如何使用 pyspark 从 s3 存储桶读取 csv 文件

    我正在使用 Apache Spark 3 1 0 和 Python 3 9 6 我正在尝试从 AWS S3 存储桶读取 csv 文件 如下所示 spark SparkSession builder getOrCreate file s3 b
  • 不获取AudioListenerInterruptionEnd触发器

    我对 OpenAl 和 MPMoviePlayerController 的组合有疑问 我在 OpenAl 设置过程中注册了 AudioInterruptionLister 当我开始播放视频时 侦听器会收到 AudioListenerInte
  • 离子 3 角度 4 动画不起作用

    我有一个组件 我正在尝试为手风琴列表设置动画 我已经进行了所有更改 例如包括import BrowserModule from angular platform browser and import BrowserAnimationsMod
  • std::unordered_set 迭代器遍历的复杂性

    我最近玩了一个std unordered set http en cppreference com w cpp container unordered set 我怀疑我的 STL 版本会跟踪某些 FILO 数据结构 看起来像列表 中的非空存
  • Android JSON解析并存储到数据库

    我正在制作一个具有数据库的应用程序 现在我正在尝试从中解析数据值
  • Kafka Streams - 减少大型状态存储的内存占用

    我有一个拓扑 见下文 可以读取一个非常大的主题 每天超过十亿条消息 这个 Kafka Streams 应用程序的内存使用量相当高 我正在寻找一些关于如何减少状态存储占用空间的建议 更多详细信息如下 Note 我并不是想逃避国有商店 我只是认
  • 清除给定 iOS 应用程序的 cookie

    我的应用程序连接到服务器 并且基于 cookie 服务器将发出不同的响应 是否无法以编程方式清除cookie存储 以便服务器下次联系服务器时无法识别我的应用程序 据我所知 清除 Settings app 中的 Cookie 仅适用于 Saf
  • 如何用R中的频率表获得中位数? [复制]

    这个问题在这里已经有答案了 Problem 我改变了问题的表述 因为似乎缺乏清晰度 所以 我们有数千家医院 他们的患者年龄在 0 岁到 100 岁之间 对于每个年龄段 他们都有一定数量的患者 例如Hospital1 有 10 名 1 岁患者
  • 动态获取路由路径

    我最近将一些模板从 ERB 转换为 Haml 大多数情况下 它变得更干净 更好 但按钮定义开始变得糟糕 我想转换这个 link to t new default gt t helpers links new new intern path
  • Python ctypes 指向结构体指针的指针

    我在获取指向工作结构的指针时遇到问题 这是我抛出异常 ArgumentError 参数 1 预期 LP LP List 实例而不是指向 LP LP List 的指针 的代码 class List Structure fields head
  • 如何将额外参数传递给 R 中 do.call 的函数参数

    我想传递参数 stringsAsFactors FALSE to rbind in do call 但以下方法不起作用 data lt do call rbind strsplit readLines home jianfezhang ad
  • 用python计算逻辑回归

    我尝试计算逻辑回归 我有 csv 文件形式的数据 看起来像 node id second major gender major index year dorm high school student fac 0 0 2 257 2007 1
  • 为什么 ts-toolbelt 库使用“Oextendsunknown”表达式

    我正在研究 ts toolbelt 库的源代码 而我也经常遇到这样的表情O extends unknown 在我看来 它没有添加任何功能 所以我想知道 它是做什么用的 hidden export type UnionOf