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;
posted @ 2022-09-21 00:41  Laggage  阅读(119)  评论(0编辑  收藏  举报