# 1367-移除索引签名
# 题目描述
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 }
# 分析
索引签名,其实在 元组转联合 中提到过,其更多定义可以在 Index Signatures (opens new window) 找到。
要想移除索引签名,可以看看如下示例:
type Foo = {
[key: string]: any;
0: 1;
test: 1;
[key: number]: any;
[key: symbol]: any;
foo(): void;
};
/*
Case1 = {
[x: string]: string;
[x: number]: number;
[x: symbol]: symbol;
0: 0;
test: "test";
foo: "foo";
}
*/
type Case1 = {
[P in keyof Foo]: P;
};
可以看出来,所谓的索引签名,核心就在于它的 key 是 string | number | symbol,而不是像 Case1 中 0 | 'test' | 'foo' 这样的常量。
根据这一点,借助类似 实现 Omit 中的 as 操作符,就可以把 string | number | symbol 这样的索引签名过滤掉。
# 题解
type isStringNumberSymbol<T> = string extends T
? never
: number extends T
? never
: symbol extends T
? never
: T;
type RemoveIndexSignature<T> = {
[P in keyof T as isStringNumberSymbol<P>]: T[P];
};
只要是 P 是 string | number | symbol 中的一个,就返回 never,从而过滤掉索引签名的 key。
注意这里用的是 string extends T
而不是 T extends string
,值得细品。
# 知识点
- 索引签名的本质,其 key 的类型是 string | number | symbol,注意不是其子类型,普通的 key 是常量 而非类型本身