类型体操刷题系列(三)——Awaited/If/Concat

189 阅读1分钟

目的

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

ts 类型体操 github 我的解答

题目大纲

  1. Easy Awaited
  2. Easy If
  3. Easy Concat

01. Easy Awaited

题目要求

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

type X = Promise<string>
type Y = Promise<{ field: number }>
type Z = Promise<Promise<string | number>>

type cases = [
  Expect<Equal<MyAwaited<X>, string>>,
  Expect<Equal<MyAwaited<Y>, { field: number }>>,
  Expect<Equal<MyAwaited<Z>, string | number>>,
]

// @ts-expect-error
type error = MyAwaited<number>

我的答案

type MyAwaited<T extends Promise<any>> = T extends Promise<infer K>
  ? K extends Promise<infer R>
    ? R
    : K
  : never;

知识点

  1. 当我们使用any的时候,后面可以通过infer关键字来推断对应的类型
  2. 这里为啥通过K extends Promise<infer R>又判断一层,因为有两层Promise嵌套的场景

2. Easy If

题目要求

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

type cases = [
  Expect<Equal<If<true, 'a', 'b'>, 'a'>>,
  Expect<Equal<If<false, 'a', 2>, 2>>,
  Expect<Equal<If<null, 'a', 'b'>, 'b'>>
]

我的解答

type If<C, T, F> = C extends true ? (C extends null ? F : T) : F;

知识点

A1. 如何判断两个类型是否相同?

Q1. 使用extends关键字即可,但是如果是never的话,需要通过函数包一层,就类似(() => T) extends () => never这样

3. Easy Concat

题目要求

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

type cases = [
  Expect<Equal<Concat<[], []>, []>>,
  Expect<Equal<Concat<[], [1]>, [1]>>,
  Expect<Equal<Concat<[1, 2], [3, 4]>, [1, 2, 3, 4]>>,
  Expect<Equal<Concat<['1', 2, '3'], [false, boolean, '4']>, ['1', 2, '3', false, boolean, '4']>>,
]

我的解答

type Concat<T extends any[], U extends any[]> = [...T, ...U];

知识点

  1. 使用...运算符在typescript中可以达到合并两个数组的效果