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 30, 2024     Ganace     Front-end-Foundation

TypeScript

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

LastIndexOf数组去重 UniqueMapTypes

Construct TupleNumber RangeCombination


中等挑战

一、LastIndexOf

实现类型版本的 Array.lastIndexOf, LastIndexOf<T, U> 接受数组 T, any 类型 U, 如果 U 存在于 T 中, 返回 U 在数组 T 中最后一个位置的索引, 不存在则返回 -1
type IsEqual<T, U> = U extends T ? (T extends U ? true : false) : false;
type LastIndexOf<T extends any[], U> = T extends [...infer L, infer R] ? (IsEqual<R, U> extends true ? L["length"] : LastIndexOf<L, U>) : -1;

二、数组去重Unique

实现类型版本的 Lodash.uniq 方法, Unique 接收数组类型 T, 返回去重后的数组类型.
type IsInclude<T, U> = U extends [infer F, ...infer Rest] ? (Equal<F, T> extends true ? true : IsInclude<T, Rest>) : false;
type Unique<T, U extends any[] = []> = T extends [infer R, ...infer F] ? (IsInclude<R, U> extends true ? Unique<F, [...U]> : Unique<F, [...U, R]>) : U;

三、MapTypes

Implement MapTypes<T, R> which will transform types in object T to different types defined by type R which has the following structure
type StringToNumber = { mapFrom: string; mapTo: number };
type StringToDate = { mapFrom: string; mapTo: Date };
MapTypes<{ iWillBeNumberOrDate: string }, StringToDate | StringToNumber>; // gives { iWillBeNumberOrDate: number | Date; }
type MapTypes<T, R extends { mapFrom: any; mapTo: any }> = {
    [K in keyof T]: T[K] extends R["mapFrom"] ? (R extends { mapFrom: T[K] } ? R["mapTo"] : never) : T[K];
};

四、Construct Tuple

构造一个给定长度的元组。

type result = ConstructTuple<2> // 期望得到 [unknown, unkonwn]

type ConstructTuple<L extends number, U extends unknown[] = []> = L extends U["length"] ? U : ConstructTuple<L, [...U, unknown]>;

五、Number Range

Sometimes we want to limit the range of numbers… For examples.

type result = NumberRange<2 , 9> // | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

type NumberRange<L extends number, H extends number, Idx extends 1[] = L extends 0 ? [] : [1, 1], Res = never> = Idx["length"] extends H
    ? H | Res
    : NumberRange<L, H, [...Idx, 1], Idx["length"] | Res>;

六、Combination

Given an array of strings, do Permutation & Combination. It’s also useful for the prop types like video controlsList

For example:

// expected to be `"foo" | "bar" | "baz" | "foo bar" | "foo bar baz" | "foo baz" | "foo baz bar" | "bar foo" | "bar foo baz" | "bar baz" | "bar baz foo" | "baz foo" | "baz foo bar" | "baz bar" | "baz bar foo"`
type Keys = Combination<["foo", "bar", "baz"]>;

Answer:

type Combination<T extends string[], All = T[number], Item = All> = Item extends string ? Item | `${Item} ${Combination<[], Exclude<All, Item>>}` : never;