Typescript類型體操 - MapTypes

題目

中文

實現 MapTypes<T, R>, 它將對象 T 中的類型轉換爲有如下結構的類型 R 定義的類型

type StringToNumber = {
    mapFrom: string; // 類型爲 string 的鍵(key)
    mapTo: number; // 會被轉換爲 number
};

示例:

type StringToNumber = { mapFrom: string; mapTo: number };
MapTypes<{ iWillBeANumberOneDay: string }, StringToNumber>; // 結果 { iWillBeANumberOneDay: number; }

注意, 用戶可能會傳入聯合(union)類型

type StringToNumber = { mapFrom: string; mapTo: number };
type StringToDate = { mapFrom: string; mapTo: Date };
MapTypes<{ iWillBeNumberOrDate: string }, StringToDate | StringToNumber>; // gives { iWillBeNumberOrDate: number | Date; }

如果類型在字典中不存在, 那就讓它保持原樣

type StringToNumber = { mapFrom: string; mapTo: number };
MapTypes<
    { iWillBeANumberOneDay: string; iWillStayTheSame: Function },
    StringToNumber
>; // // gives { iWillBeANumberOneDay: number, iWillStayTheSame: Function }

English

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; // value of key which value is string
    mapTo: number; // will be transformed for number
};

Examples:

type StringToNumber = { mapFrom: string; mapTo: number };
MapTypes<{ iWillBeANumberOneDay: string }, StringToNumber>; // gives { iWillBeANumberOneDay: number; }

Be aware that user can provide a union of types:

type StringToNumber = { mapFrom: string; mapTo: number };
type StringToDate = { mapFrom: string; mapTo: Date };
MapTypes<{ iWillBeNumberOrDate: string }, StringToDate | StringToNumber>; // gives { iWillBeNumberOrDate: number | Date; }

If the type doesn't exist in our map, leave it as it was:

type StringToNumber = { mapFrom: string; mapTo: number };
MapTypes<
    { iWillBeANumberOneDay: string; iWillStayTheSame: Function },
    StringToNumber
>; // // gives { iWillBeANumberOneDay: number, iWillStayTheSame: Function }

答案

type MapTypes<T, R extends { mapFrom: unknown; mapTo: unknown }> = {
    [P in keyof T]: T[P] extends R['mapFrom']
        ? R extends R
            ? Equal<T[P], R['mapFrom']> extends true
                ? R['mapTo']
                : never
            : never
        : T[P];
};

在線演示

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章