类型体操刷题系列(十八)— ObjectEntries/Shift/TupleNestedObject

209 阅读1分钟

目的

Github上的类型体操,让你写出更加优雅的TS类型定义,以及探寻TS中我们不熟悉的只是,让我们开始TS的类型挑战把~2022希望通过更文的方式来督促自己学习,每日三题,坚持日更不断~~

题目大纲

  1. Medium Object Entries
  2. Medium Shift
  3. Medium Tuple Nested Object

01. Medium Object Entries

题目要求

import { Equal, Expect, ExpectFalse, NotEqual } from '@type-challenges/utils'

interface Model {
  name: string;
  age: number;
  locations: string[] | null;
}

type ModelEntries = ['name', string] | ['age', number] | ['locations', string[] | null];



type cases = [
  Expect<Equal<ObjectEntries<Model>,ModelEntries>>,
  Expect<Equal<ObjectEntries<Partial<Model>>,ModelEntries>>,
]

我的答案

type ObjectEntries<
  T extends object,
  R extends T = {
    [K in keyof T]-?: T[K];
  },
  K extends keyof R = keyof R
> = K extends K ? [K, R[K]] : [];

知识点

  1. -的使用方法,这样可以去除undefined
  2. 使用K extends K去除泛型类型

2. Medium Shift

题目要求

import { Equal, Expect, ExpectFalse, NotEqual } from '@type-challenges/utils'

type cases = [
  Expect<Equal<Shift<[3, 2, 1]>, [2, 1]>>,
  Expect<Equal<Shift<['a', 'b', 'c', 'd', ]>, ['b', 'c', 'd']>>,
]

我的解答

type Shift<T extends any[]> = T extends [infer P, ...infer X] ? X : never

知识点

  1. 数组infer的推断

3. Medium Tuple Nested Object

题目要求

import { Equal, Expect, ExpectFalse, NotEqual } from '@type-challenges/utils'

type cases = [
  Expect<Equal<TupleToNestedObject<['a'], string>, {a: string}>>,
  Expect<Equal<TupleToNestedObject<['a', 'b'], number>, {a: {b: number}}>>,
  Expect<Equal<TupleToNestedObject<['a', 'b', 'c'], boolean>, {a: {b: {c: boolean}}}>>,
  Expect<Equal<TupleToNestedObject<[], boolean>, boolean>>,
]

我的解答

type TupleToNestedObject<T extends string[], U> = T["length"] extends 0
  ? U
  : T extends [...infer R, infer P]
  ? R extends string[]
    ? P extends string
      ? TupleToNestedObject<R, { [key in P]: U }>
      : never
    : never
  : never;

知识点

  1. 如何判断一个数组遍历完了,就是length extends 0