typescript - 为什么 ts-toolbelt 库使用“O 扩展未知”表达式
问题描述
我正在研究 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 ? ... : never
检查看似无所事事,却导致了这种情况的发生。
看起来它们什么都不做但实际上分布在联合之间的表达式,什么时候T
是泛型类型参数:
T extends unknown ? ... : never
T extends any ? ... : never
T extends T ? ... : never
如果T
是类型参数,如在泛型函数function foo<T>(/*...*/): void
或泛型接口interface Foo<T> {/*...*/}
中,则形式的类型T extends XXX ? YYY : ZZZ
是分布条件类型。
它将条件检查分布在. T
当T
指定了某个特定类型时,编译器将该类型拆分为其联合成员,评估每个此类成员的检查,然后将结果连接回一个新的联合。因此,如果F<T>
跨工会分布,则将F<A | B | C>
与F<A> | F<B> | F<C>
.
并非所有类型函数都是跨联合分布的。例如,运算keyof
符不会将输入的并集转换为输出的并集:
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
如果你有一个在联合中不是分布式的类型函数并且你希望它是,你可以将它包装在一个分布式条件类型中:
type DistribKeyof<T> = T extends unknown ? keyof T : never;
type UnionKeyofAorB = DistribKeyof<{ a: string } | { b: number }>; // "a" | "b"
因此在工会之间UnionOf
是分布的:
type Correct = UnionOf<{ a: string } | { b: number }>
// string | number
推荐阅读
- java - 如何在三星 Galaxy S10 或 S10+ 中测试接近传感器?
- css - 锚标记中的 Svg 图标可单击,但在 Microsoft Edge 或 IE 11 中不起作用
- c - 从已知地址访问数组
- javascript - 未捕获的类型错误:无法解析模块说明符 X。相对引用必须以“/”、“./”或“../”开头
- r - 如何在 R 中为随机森林模型运行 ANOVA 函数?
- java - 如何在 Spring Boot 应用程序中配置自定义数据库连接超时?
- tensorflow - Keras,使用空类别进行训练
- python-3.x - 无法在 BigQuery 中使用 DML 语句的作业中设置目标表
- c# - 当某些并行进程执行繁重的工作时,数据流会阻塞
- angular - 如何在Angular 4中将选定的复选框值保存在数据库中而不是true false