Typescript類型體操 - RemoveIndexSignature

題目

中文

實現 RemoveIndexSignature<T>, 將索引字段從對象中排除掉.

示例:

type Foo = {
    [key: string]: any;
    foo(): void;
};
type A = RemoveIndexSignature<Foo>; // expected { foo(): void }

English

Implement RemoveIndexSignature<T> , exclude the index signature from object types.

For example:

type Foo = {
    [key: string]: any;
    foo(): void;
};
type A = RemoveIndexSignature<Foo>; // expected { foo(): void }

答案

type RemoveIndexSignature<T extends object> = {
    [P in keyof T as string extends P
        ? never
        : number extends P
        ? never
        : symbol extends P
        ? never
        : P]: T[P];
};

在線演示

解析

關鍵在於理解當對一個包含索引簽名(Index Signature)的對象類型執行keyof會返回什麼, 看下面幾個例子:

type Foo = keyof { [key: string]: any }; // Foo 的類型是 string | number
type Bar = keyof { [key: symbol]: any }; // Bar 的類型是 symbol
type FooBar = keyof { [key: string | number | symbol]: any }; // FooBar 的類型是 string | number | symbol
type FooFoo = keyof { name: string; age: string }; // FooFoo的類型是 'name' | 'age'

keyof某個對象時, 對象中普通的字段會變成字面量類型, 對應上面例子中的FooFoo, 而索引簽名會變成 string number symbol 這些類型組合出來的聯合類型, 知道了這點就可以判斷是否爲索引簽名了

type isIndexSignature<T> = string extends T
    ? true
    : number extends T
    ? true
    : symbol extends T
    ? true
    : false;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章