我打算写一个助手类型,它与元组类型中的所有类型相交,但要记住一个逻辑:
添加最多限制的类型";获胜";超过其他人。最后的交集必须是可以分配给元组的每个单独类型的最受限制的类型。
一个例子。让我们将该助手类型称为Join
。以下是一些断言:
Join<[string, any[]]> // string & any[]
Join<[string, number, boolean]> // never (string & number & boolean)
Join<[string, { z: boolean }]> // string & { z: boolean }
Join<[{ x: number }, { y: string }]> // { x: number } & { y: string }
Join<[{ x: number }, { y: string }, { z: boolean }]> // { x: number } & { y: string } & { z: boolean }
Join<[any, { y: string }]> // { y: string }
Join<[any, string]> // string
Join<[unknown, string]> // string
Join<[any, unknown, any, any]> // unknown
Join<[any, any, any]> // any
我不知道从哪里开始。知道吗?非常感谢。
// credits goes to https://stackoverflow.com/a/50375286
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
k: infer I
) => void
? I
: never;
type Elem = any;
type FilterAny<
Arr extends ReadonlyArray<Elem>,
Result extends ReadonlyArray<Elem> = []
> = Arr extends []
? Result
: Arr extends readonly [infer H, ...infer Tail]
? Tail extends ReadonlyArray<Elem>
? IsAny<H> extends true
? FilterAny<Tail, Result>
: FilterAny<Tail, [...Result, H]>
: never
: never;
type Join<T extends any[]> =
FilterAny<T>['length'] extends 0
? any
: UnionToIntersection<FilterAny<T>[number]>
// credits goes to https://stackoverflow.com/questions/55541275/typescript-check-for-the-any-type
type IsAny<T> = 0 extends (1 & T) ? true : false;
type Result1 = Join<[string, any[]]> // string & any[]
type Result2 = Join<[string, number, boolean]> // never (string & number & boolean)
type Result3 = Join<[string, { z: boolean }]> // string & { z: boolean }
type Result4 = Join<[{ x: number }, { y: string }]> // { x: number } & { y: string }
type Result5 = Join<[{ x: number }, { y: string }, { z: boolean }]> // { x: number } & { y: string } & { z: boolean }
type Result6 = Join<[any, { y: string }]> // { y: string }
type Result7 = Join<[any, string]> // string
type Result8 = Join<[unknown, string]> // string
type Result9 = Join<[any, unknown, any, any]> // unknown
type Result10 = Join<[any, any, any]> // any
FilterAny
递归地迭代元组并从元组中移除所有any
Join
逻辑:
- 如果
FilterAny
返回空数组-返回any
- 返回所有数组元素并集的交集
您可以在我的博客中找到更多元组操作的示例
游乐场
我做了一些尝试,这将支持您期望的所有案例,所以您可以迭代:
type IfAny<Test, True, False> = 0 extends (1 & Test) ? True : False
type Join<Arr extends [...any[]]> = Arr extends [infer A] ? A : Arr extends [infer A, ...infer Rest] ?
IfAny<A, Join<Rest>, A & Join<Rest>> : any
唯一不符合您规范的是
type Test = Join<[any, unknown, any, any]> // you want unknown and it is any