【Typescript】type-challenges:medium级别题目(一)

103 阅读3分钟

image.png

1、实现 Get Return Type

题目内容

1682500990979.png

题目解析

涉及知识点: infer

这题就很简单了,我们只要返回函数最终的返回值类型就好了。

使用 infer 推断函数返回的类型,有就有,没有就是never。

题目答案
    // ============= Your Code Here =============
    type MyReturnType<T> = T extends (...args: any[]) => infer P ? P : never

2、实现 Omit

题目内容

1682501286888.png

题目解析

涉及知识点: keyof 、 extends

本题主要就是剔除一些不需要的属性,因此需要注意几点:

  1. K是要剔除的属性,肯定是T的属性中的,所以 K extends keyof T;

  2. 需要剔除K中列出的属性,只需要在返回的属性 keyod T 中过滤掉K中列出的属性即可 [P in Exclude<keyof T, K>].

题目答案
    // ============= Your Code Here =============
   type Exclude<T, U> = T extends U ? never : T
   type MyOmit<T, K extends keyof T> = {
      [P in Exclude<keyof T, K>] : T[P]
   }


3、实现 Readonly 2

题目内容

1682501811918.png

题目解析

涉及知识点: keyof 、 as

easy难度的时候,已经有过一篇关于readonly的题目,忘记的可自行查看

本题呢则是增加了一点点难度,就是给部分属性增加readonly。

那么就简单了,我们只需要给需要的增加readonly,也就是属于K 里的都需要是readonly,不属于K里的都不是。

as P extends K ? P : never, 这里增加as是为了过滤,已经存在过的就不需要再次判断了。

题目答案
    // ============= Your Code Here =============
    type MyReadonly2<T, K extends keyof T = keyof T> = {
      [P in keyof T as P extends K ? never: P] : T[P]
    } & {
      readonly [P in keyof T as P extends K ? P : never] : T[P]
    }

4、实现 Deep Readonly

题目内容

1682502512503.png

For example:

type X = { 
  x: { 
    a: 1
    b: 'hi'
  }
  y: 'hey'
}

type Expected = { 
  readonly x: { 
    readonly a: 1
    readonly b: 'hi'
  }
  readonly y: 'hey' 
}

type Todo = DeepReadonly<X> // should be same as `Expected`

题目解析

涉及知识点: keyof 、 readonly

与上题也是关于readonly的。前面也说了,easy难度的时候,已经有过一篇关于readonly的题目,忘记的可自行查看

本题其实就是基于easy的难度readonly,增加一个判断,如果T[K] 返回依然是个对象,那就继续深度遍历下去。

如何判别返回的是不是个对象呢?只要判断 T[K] 还有没有属性名即可,keyof T[K] extends never。

题目答案
    // ============= Your Code Here =============
     type DeepReadonly<T> = {
      readonly [K in keyof T] : keyof T[K] extends never ? T[K] : DeepReadonly<T[K]>
    }

5、实现 Tuple to Union

题目内容

1682502972967.png

题目解析

涉及知识点: Tuple

我觉得这题不需要解析了。。。

题目答案
    // ============= Your Code Here =============
    type TupleToUnion<T extends any[]> = T[number]

6、实现 Chainable Options

题目内容

1682503161499.png

For example:


declare const config: Chainable

const result = config
  .option('foo', 123)
  .option('name', 'type-challenges')
  .option('bar', { value: 'Hello World' })
  .get()

// expect the type of result to be:
interface Result {
  foo: number
  name: string
  bar: {
    value: string
  }
}

你只需要在类型层面实现这个功能 - 不需要实现任何 TS/JS 的实际逻辑。

你可以假设 key 只接受字符串而 value 接受任何类型,你只需要暴露它传递的类型而不需要进行任何处理。同样的 key 只会被使用一次。

题目解析

涉及知识点: extends

其实就是实现一个Chainable, 有两个属性 option 和 get。

option就是不断的定义属性名和属性值,每一定义好的 key-value 都拼接到T中,形成一个对象;

get就是返回返回形成的这个对象 T 。

题目答案
  // ============= Your Code Here =============
  type Chainable<T = {}> = {
      option<K extends string, V extends any>(key: K, value: V)
        : Chainable<T & { [P in K] : V }>
      get(): T
}

tips:

Medium级别的题目总共有75题,为了方便少量多次查看,缓解疲劳,我们就以6题为一篇进行。