You don't have javascript enabled. Good luck! :(

欢迎页

Welcome to Ganace's Blog


欢迎您来到Ganace 的个人博客。

在茫茫互联网的海洋里能够遇见,实在是一份不小的幸运。

诚挚地向您问候一声:您好,朋友!

这里是属于Ganace个人的隐秘小空间,记录了工作学习中遇到的知识点与灵感,以及生活中的碎碎念与吐槽突如其来的中二病尬尬的文艺时间锻炼腹肌的时刻惊喜的小发现等等。

想要在自己的平淡无奇的人生长河中留下些什么,

或者只是为了拯救老人家岌岌可危的记忆力,

仅此而已。

来到此地,分享与你。

也期待与您的再次相遇!

Share with Me


有任何的分享或者建议与吐槽,都可以Email我:ganace@foxmail.com

欢迎您的来信!

【TypeScript】TypeScript类型体操(十) 中等挑战

  Mar 27, 2024     Ganace     Front-end-Foundation

TypeScript

TypeScript 的类型体操笔记,温故知新。

反转 Reverse函数参数类型反转 Flip Arguments数组深度展开 FlattenDepth

BEM style stringInorderTraversalFlip


中等挑战

一、反转 Reverse

实现类型版本的数组反转 Array.reverse

例如

` type b = Reverse<[‘a’, ‘b’, ‘c’]> // [‘c’, ‘b’, ‘a’]`

type Reverse<T extends unknown[]> = T extends [infer F, ...infer R] ? [...Reverse<R>, F] : T;

二、函数参数类型反转 Flip Arguments

Implement the type version of lodash’s _.flip.

Type FlipArguments<T> requires function type T and returns a new function type which has the same return type of T but reversed parameters.

For example:

type Flipped = FlipArguments<(arg0: string, arg1: number, arg2: boolean) => void> // (arg0: boolean, arg1: number, arg2: string) => void

Answer:

type Reverse<T extends unknown[]> = T extends [infer F, ...infer R] ? [...Reverse<R>, F] : [];
type FlipArguments<T extends (...args: any[]) => any> = T extends (...args: infer P) => infer U ? (...args: Reverse<P>) => U : never;

三、数组深度展开 FlattenDepth

Recursively flatten array up to depth times.

For example:

type a = FlattenDepth<[1, 2, [3, 4], [[[5]]]], 2> // [1, 2, 3, 4, [5]]. flattern 2 times type b = FlattenDepth<[1, 2, [3, 4], [[[5]]]]> // [1, 2, 3, 4, [[5]]]. Depth defaults to be 1

Answer:

type FlattenDepth<T extends any[], C extends number = 1, U extends any[] = []> = T extends [infer F, ...infer R]
    ? F extends any[]
        ? U["length"] extends C
            ? [F, ...FlattenDepth<R, C, U>]
            : [...FlattenDepth<F, C, [0, ...U]>, ...FlattenDepth<R, C, U>]
        : [F, ...FlattenDepth<R, C, U>]
    : T;

四、BEM style string

For example, the block component would be represented as btn, element that depends upon the block would be represented as btnprice, modifier that changes the style of the block would be represented as btn–big or btnprice–warning.

Implement BEM<B, E, M> which generate string union from these three parameters. Where B is a string literal, E and M are string arrays (can be empty).

Test Cases:

type cases = [
    Expect<Equal<BEM<"btn", ["price"], []>, "btn__price">>,
    Expect<Equal<BEM<"btn", ["price"], ["warning", "success"]>, "btn__price--warning" | "btn__price--success">>,
    Expect<Equal<BEM<"btn", [], ["small", "medium", "large"]>, "btn--small" | "btn--medium" | "btn--large">>
];

Answer:

type BEM<B extends string, E extends string[], M extends string[]> = `${B}${E extends [] ? "" : `__${E[number]}`}${M extends [] ? "" : `--${M[number]}`}`;

五、InorderTraversal

Implement the type version of binary tree inorder traversal.

For example:

const tree1 = {
    val: 1,
    left: null,
    right: {
        val: 2,
        left: {
            val: 3,
            left: null,
            right: null,
        },
        right: null,
    },
} as const;

type A = InorderTraversal<typeof tree1>; // [1, 3, 2]

Answer:

type InorderTraversal<T extends TreeNode | null> = T extends TreeNode ? [...InorderTraversal<T["left"]>, T["val"], ...InorderTraversal<T["right"]>] : [];

六、Flip

Implement the type of just-flip-object. Examples:
Flip<{ a: "x", b: "y", c: "z" }>; // {x: 'a', y: 'b', z: 'c'}
Flip<{ a: 1, b: 2, c: 3 }>; // {1: 'a', 2: 'b', 3: 'c'}
Flip<{ a: false, b: true }>; // {false: 'a', true: 'b'}
type Flip<T extends Record<string, string | boolean | number>> = {
  [K in keyof T as `${T[K]}`]: K
}