Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

「重学TS 2.0 」TS 练习题第四十九题 #95

Open
heweijian4933 opened this issue Jun 4, 2022 · 4 comments
Open

「重学TS 2.0 」TS 练习题第四十九题 #95

heweijian4933 opened this issue Jun 4, 2022 · 4 comments

Comments

@heweijian4933
Copy link

实现 UnionToArray 工具类型,用于将联合类型转换成元组类型。具体的使用示例如下所示:

type UnionToArray<U> = // 你的实现代码

type A0 = UnionToArray<'aaa' | 'bbb' | 'ccc'> //=> ['aaa' , 'bbb' , 'ccc']
type A1 = UnionToArray<1 | 2 | 3 > //=> [1, 2, 3]
type A2 = UnionToArray<{type:'input'} | {type:'select',hasOptions:boolean}> //=> [{type:'input'} ,{type:'select',hasOptions:boolean}]
@SuperSaiyr
Copy link

type UnionToIntersection<U> = (U extends any ? (arg: U) => any : never) extends (arg: infer I) => void ? I : never;

type UnionToTuple<T> = UnionToIntersection<T extends any ? (t: T) => T : never> extends (_: any) => infer W
    ? [...UnionToTuple<Exclude<T, W>>, W]
    : [];

@lq-math-dog
Copy link

lq-math-dog commented Aug 9, 2022

//疑问 非答案
type A5 = T extends T ? T : never
type A51 = A5<1 | 2 | 3>;//type A51 = 2 | 1 | 3
type A6 = T extends T ? [T] : never
type A61 = A6<1 | 2 | 3>; //type A61 = [1] | [2] | [3]
//采用上面解法的时候 为什么数字会乱序,字符串则不会
type A1 = UnionToArray<1 | 2 | 3 > //=> [1, 2, 3] //预期
type A1 = UnionToArray<1 | 2 | 3 >//=>[2,1,3] //实际显示
// 🤔🤔🤔🤔🤔🤔🤔

//后面在同事的电脑上 打印同样的A51和A61
//结果没有乱序
//可能原因 vscode插件的影响
//忽略上面的提问

@SongJuXin
Copy link

SongJuXin commented Oct 6, 2022

做不到,因为联合类型是无序的,而元组是有序的。

这个不太满足要求:

type UnionToArray<U,T extends U=U> = [U] extends [never]
  ?[]
  :U extends  U?[U,...UnionToArray<Exclude<T,U>>]:[]
type A0 = UnionToArray<'a' | 'b' | 'c'> 
//=>type A0 = ["a", "b", "c"] | ["a", "c", "b"] | ["b", "a", "c"] | ["b", "c", "a"] | ["c", "a", "b"] | ["c", "b", "a"]

这个基本满足要求:

class BHAAL { private isBhaal = true; }

type UnionToTuple<T> = (
    (
        (
            T extends any
                ? (t: T) => T
                : never
        ) extends infer U
            ? (U extends any
                ? (u: U) => any
                : never
            ) extends (v: infer V) => any
                ? V
                : never
            : never
    ) extends (_: any) => infer W
        ? [...UnionToTuple<Exclude<T, W>>, W]
        : []
);

type Tuple = UnionToTuple<2 | 1 | 3 | 5 | 10 | -9 | 100 | 1001 | 102 | 123456 | 100000000 | "alice" | [[[BHAAL]]] | "charlie">;
//     ^? = [2, 1, 3, 5, 10, -9, 100, 1001, 102, 123456, 100000000, "alice", [[[BHAAL]]], "charlie"]

更多信息看这里microsoft/TypeScript#13298

@zhengyimeng
Copy link

type UnionToArray<U> = (U extends any ? (arg: [U]) => any : never) extends (
  ...arg: infer R
) => any
  ? R extends [arg: [infer O]]
    ? [...UnionToArray<Exclude<U, O>>, O]
    : []
  : never;

type A0 = UnionToArray<"aaa" | "bbb" | "ccc">; //=> ['aaa' , 'bbb' , 'ccc']
type A1 = UnionToArray<1 | 2 | 3>; //=> [1, 2, 3]
type A2 = UnionToArray<
  { type: "input" } | { type: "select"; hasOptions: boolean }
>; //=> [{type:'input'} ,{type:'select',hasOptions:boolean}]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants