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

TypeScript

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

FillTrim Right去除数组指定元素

TruncIndexOfJoin


中等挑战

一、Fill

Fill, a common JavaScript function, now let us implement it with types. Fill<T, N, Start?, End?>, as you can see,Fill accepts four types of parameters, of which T and N are required parameters, and Start and End are optional parameters. The requirements for these parameters are: T must be a tuple, N can be any type of value, Start and End must be integers greater than or equal to 0.

type exp = Fill<[1, 2, 3], 0> // expected to be [0, 0, 0]

type Fill<T extends unknown[], N, Start extends number = 0, End extends number = T["length"], L extends any[] = []> = T extends [infer F, ...infer R]
    ? [...L, 0][Start] extends undefined
        ? Fill<R, N, Start, End, [...L, F]>
        : [...L, 0][End] extends undefined
        ? Fill<R, N, Start, End, [...L, N]>
        : Fill<R, N, Start, End, [...L, F]>
    : L;

二、Trim Right

实现 TrimRight<T> ,它接收确定的字符串类型并返回一个新的字符串,其中新返回的字符串删除了原字符串结尾的空白字符串。

type Trimed = TrimRight<' Hello World '> // 应推导出 ' Hello World'

type TrimRight<S extends string> = S extends `${infer L}${" " | "\n" | "\t"}` ? TrimRight<L> : S;

三、去除数组指定元素

实现一个像 Lodash.without 函数一样的泛型 Without<T, U>,它接收数组类型的 T 和数字或数组类型的 U 为参数,会返回一个去除 U 中元素的数组 T

例如:

type Res = Without<[1, 2], 1>; // expected to be [2]
type Res1 = Without<[1, 2, 4, 1, 5], [1, 2]>; // expected to be [4, 5]
type Res2 = Without<[2, 3, 2, 3, 2, 3, 2, 3], [2, 3]>; // expected to be []
type Without<T extends unknown[], U extends unknown | unknown[]> = T extends [infer F, ...infer R]
    ? F extends U
        ? Without<R, U>
        : U extends unknown[]
        ? F extends U[number]
            ? Without<R, U>
            : [F, ...Without<R, U>]
        : [F, ...Without<R, U>]
    : T;

四、Trunc

Implement the type version of Math.trunc, which takes string or number and returns the integer part of a number by removing any fractional digits.

type A = Trunc<12.34> // 12

type Trunc<T extends string | number> = `${T}` extends `${infer F}.${infer _}` ? (F extends "" ? "0" : F) : `${T}`;

五、IndexOf

Implement the type version of Array.indexOf, indexOf<T, U> takes an Array T, any U and returns the index of the first U in Array T.

For example:

type Res = IndexOf<[1, 2, 3], 2>; // expected to be 1
type Res1 = IndexOf<[2, 6, 3, 8, 4, 1, 7, 3, 9], 3>; // expected to be 2
type Res2 = IndexOf<[0, 0, 0], 2>; // expected to be -1

Answer:

type IndexOf<T extends unknown[], U, N extends unknown[] = []> = T extends [infer F, ...infer R] ? (Equal<F, U> extends true ? N["length"] : IndexOf<R, U, [...N, F]>) : -1;
TypeScript提供的工具类型:

ReturnType<Type> 构造一个由函数 Type 的返回类型组成的类型。

六、Join

Implement the type version of Array.join, Join<T, U> takes an Array T, string or number U and returns the Array T with U stitching up.

For example:

type Res = Join<["a", "p", "p", "l", "e"], "-">; // expected to be 'a-p-p-l-e'
type Res1 = Join<["Hello", "World"], " ">; // expected to be 'Hello World'
type Res2 = Join<["2", "2", "2"], 1>; // expected to be '21212'
type Res3 = Join<["o"], "u">; // expected to be 'o'

Answer:

type Join<T extends any[], U extends string | number = ","> = T extends [infer F extends string, ...infer R] ? (R["length"] extends 0 ? `${F}` : `${F}${U}${Join<R, U>}`) : "";