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

TypeScript

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

剔除指定字符 Drop Char数字减一 MinusOnePickByType

StartsWithEndsWithPartialByKeys


中等挑战

一、剔除指定字符 Drop Char

从字符串中剔除指定字符。
type DropChar<S extends string, C extends string> = S extends `${infer L}${C}${infer R}` ? DropChar<`${L}${R}`, C> : S;

二、数字减一 MinusOne

给定一个正整数作为类型的参数,要求返回的类型是该数字减 1。
// Reverses a string: '123' -> '321'
type Reverse<S extends string, A extends string = ""> = S extends `${infer F}${infer R}` ? Reverse<R, `${F}${A}`> : A;

// Subtract one from a digit: '1' -> '0', '5' -> '4', '0' -> '9'
type DigitMinusOne<D extends string> = "09876543210" extends `${string}${D}${infer R}${string}` ? R : never;

// Subtract one from a reversed number: '5' -> '4', '01' -> '9', '51' -> '41', '001' -> '99'
type RevMinusOne<T extends string> = T extends `${infer F}${infer N}${infer R}`
    ? // if `T` is a multi-digit number like '01', '55' or '123'
      F extends "0"
        ? `9${RevMinusOne<`${N}${R}`>}`
        : `${DigitMinusOne<F>}${N}${R}`
    : // if `T` is a single-digit number like '0', '1' or '8'
    T extends "0"
    ? "1-"
    : T extends "1"
    ? ""
    : DigitMinusOne<T>;

// Reverse `T`, subtract one from reversed, reverse back, and convert to number
type MinusOne<T extends number> = Reverse<RevMinusOne<Reverse<`${T}`>>> extends `${infer Res extends number}` ? Res : 0;

三、PickByType

From T, pick a set of properties whose type are assignable to U.
// For Example
type OnlyBoolean = PickByType<
    {
        name: string;
        count: number;
        isReadonly: boolean;
        isEnable: boolean;
    },
    boolean
>; // { isReadonly: boolean; isEnable: boolean; }
type PickByType<T, U> = {
    [K in keyof T as T[K] extends U ? K : never]: U;
};

四、StartsWith

实现StartsWith<T, U>,接收两个string类型参数,然后判断T是否以U开头,根据结果返回truefalse
type StartsWith<T extends string, U extends string> = T extends `${U}${infer R}` ? true : false;
type StartsWith<T extends string, U extends string> = T extends `${U}${string}` ? true : false;

五、EndsWith

实现EndsWith<T, U>,接收两个string类型参数,然后判断T是否以U结尾,根据结果返回truefalse
type EndsWith<T extends string, U extends string> = T extends `${string}${U}` ? true : false;

六、PartialByKeys

实现一个通用的PartialByKeys<T, K>,它接收两个类型参数 T 和 K。

K指定应设置为可选的 T 的属性集。当没有提供K时,它就和普通的Partial<T>一样使所有属性都是可选的。

type Merge<T> = {
    [K in keyof T]: T[K];
};

type PartialByPs<T extends {}, K extends keyof T = any> = Merge<
    {
        [P in keyof T as P extends K ? P : never]?: T[P];
    } & {
        [P in keyof T as P extends K ? never : P]: T[P];
    }
>;