type-challenges:Remove Index Signature

52 阅读1分钟

Remove Index Signature

问题描述

实现 RemoveIndexSignature < T > ,从对象类型中排除索引签名。

举例:

type Foo = {
  [key: string]: any
  foo(): void
}
​
type A = RemoveIndexSignature<Foo> // expected { foo(): void }
// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'type Foo = {
  [key: string]: any
  foo(): void
}
​
type Bar = {
  [key: number]: any
  bar(): void
  0: string
}
​
const foobar = Symbol('foobar')
type FooBar = {
  [key: symbol]: any
  [foobar](): void
}
​
type Baz = {
  bar(): void
  baz: string
}
​
type cases = [
  Expect<Equal<RemoveIndexSignature<Foo>, { foo(): void }>>,
  Expect<Equal<RemoveIndexSignature<Bar>, { bar(): void; 0: string }>>,
  Expect<Equal<RemoveIndexSignature<FooBar>, { [foobar](): void }>>,
  Expect<Equal<RemoveIndexSignature<Baz>, { bar(): void; baz: string }>>
]
​
// ============= Your Code Here =============
// 答案
type RemoveIndexSignature<T, P = PropertyKey> = {
  [K in keyof T as P extends K ? never : K extends P ? K : never]: T[K]
}
​

这段代码定义了一个名为RemoveIndexSignature的类型操作符,它接受两个类型参数TPT是将被操作的对象类型,P是用于指定要删除的索引签名的类型。默认情况下,P的值为PropertyKey,表示要删除的索引签名可以是任何属性键。

实现原理:

  1. 使用keyof T遍历对象T的所有键。
  2. 对于每个键,使用as P extends K ? never : K extends P ? K : never来判断键是否满足条件。
  3. 如果满足条件,则将键从结果对象中删除。
  4. 否则,将键保留在结果对象中,并将其值设置为对象T中相应键的值。