一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情。
题目七:awaited
// template.ts
type MyAwaited = any
// test-cases.ts
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>
通过测试代码我们可以知道,MyAwaited 接收一个 Promise 类型的参数,返回 Promise 类型参数内的参数。
并且 Promise 类型内还可以嵌套另外一个 Promise,我们最终需要返回的是最里面的普通类型
接下来,来实现我们的代码:
- 首先,我们知道
MyAwaited接收的是一个Promise
type MyAwaited<T extends Promise<any>> = any
- 我们需要返回
Promise内的类型(仅条件类型的 "extends" 子句中才允许 "infer" 声明。)
type MyAwaited<T extends Promise<any>> = T extends Promise<infer P> ? P : T
此时,我们就返回 Promise 内部的类型 P 了。
Promise嵌套问题
如果传入的参数 Promise 内部还嵌套了 Promise 的话,此时的 P 就依然还是一个 Promise
type MyAwaited<T extends Promise<any>> = T extends Promise<infer P>
? P extends Promise<any>
? MyAwaited<P>
: P
: T
题目八:if
// template.ts
type If<C, T, F> = any
// test-cases.ts
import { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<If<true, 'a', 'b'>, 'a'>>,
Expect<Equal<If<false, 'a', 2>, 2>>,
]
// @ts-expect-error
type error = If<null, 'a', 'b'>
根据测试代码可以知道,If 接收三个参数,并根据第一个参数是 true 还是 false 来确定是返回第二个参数还是第三个参数
- 第一个参数明显是
boolean类型
type If<C extends boolean, T, F> = any
- 如果
C是true的话,返回T,否则返回F
type If<C extends boolean, T, F> = C extends true ? T : F
题目九:concat
// template.ts
type Concat<T, U> = any
// test-cases.ts
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']>>,
]
观察测试用例:
Concat接收两个参数,并且都是any类型的数组- 得到的结果是两个参数数组合并成的一个数组,并且顺序和参数传入顺序一致
限制参数传入类型
type Concat<T extends any[], U extends any[]> = any
合并数组
在 ts 类型的数组类型中,也可以使用类似 js 的扩展运算符。
type Concat<T extends any[], U extends any[]> = [...T, ...U]