[TypeScript] Type Challenges #1367 - Remove Index Signature

49 阅读1分钟

题目描述

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 }

题解

// ============= 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 in keyof T 
    as number extends P 
      ? never 
      : string extends P 
        ? never 
        : symbol extends P 
          ? never 
          : P
  ]: T[P]
}
  • 遍历T的每个键P

    • [P in keyof T]:遍历T的所有键
  • 条件映射:

    • as number extends P ? never : string extends P ? never : symbol extends P ? never : P

    • 如果number可以赋值给P,说明P是一个可以接受任意number键的索引签名,则映射为never

    • 如果string可以赋值给P,说明P是一个可以接受任意string键的索引签名,则映射为never

    • 如果symbol可以赋值给P,说明P是一个可以接受任意symbol键的索引签名,则映射为never

    • 否则,保留键P

  • 类型赋值:

    • T[P]:保留T中的每个键P的值