我正在研究 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
Run Code Online (Sandbox Code Playgroud)
由于某种原因,不是导出_UnionOf类型,而是在其前面加上表达式O extends unknown
据推测,库作者认为UnionOf<A | B | C>应该产生与 相同的结果UnionOf<A> | UnionOf<B> | UnionOf<C>,而 的定义_UnionOf并没有这样做。O extends unknown ? ... : never看似没有任何作用的支票却导致了这种情况的发生。
T当是泛型类型参数时,表达式看起来什么也不做,但实际上分布在联合中:
T extends unknown ? ... : neverT extends any ? ... : neverT 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
Run Code Online (Sandbox Code Playgroud)
同样,在联合体之间不具有分配性(与它在定义中_UnionOf使用的事实有关):keyof
type Oops = _UnionOf<{ a: string } | { b: number }>
// never
Run Code Online (Sandbox Code Playgroud)
如果您有一个在联合中不具有分配性的类型函数,而您希望它具有分配性,则可以将其包装在分配性条件类型中:
type DistribKeyof<T> = T extends unknown ? keyof T : never;
type UnionKeyofAorB = DistribKeyof<{ a: string } | { b: number }>; // "a" | "b"
Run Code Online (Sandbox Code Playgroud)
因此在工会之间UnionOf 是分布式的:
type Correct = UnionOf<{ a: string } | { b: number }>
// string | number
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
754 次 |
| 最近记录: |