实现一个通用First<T>,它接受一个数组T并返回它的第一个元素的类型。
如果是空数组(也就是never[])返回never,其他数组返回第一元素的类型
type First<T extends any[]> = T extends never[] ? never : T[0]type cases = [Expect<Equal<First<[3, 2, 1]>, 3>>,Expect<Equal<First<[() => 123, { a: string }]>, () => 123>>,Expect<Equal<First<[]>, never>>,Expect<Equal<First<[undefined]>, undefined>>]
获取元组长度
创建一个通用的Length,接受一个readonly的数组,返回这个数组的长度。
接受一个 readonly 数组,必需在泛型传入时约束,否则 test case 过不了
type Length<T extends readonly unknown[]> = T['length']/* _____________ 测试用例 _____________ */import { Equal, Expect } from '@type-challenges/utils'const tesla = ['tesla', 'model 3', 'model X', 'model Y'] as constconst spaceX = ['FALCON 9', 'FALCON HEAVY', 'DRAGON', 'STARSHIP', 'HUMAN SPACEFLIGHT'] as consttype cases = [Expect<Equal<Length<typeof tesla>, 4>>,Expect<Equal<Length<typeof spaceX>, 5>>,// @ts-expect-errorLength<5>,// @ts-expect-errorLength<'hello world'>,]
如果不是上面的 test case 的话
type Length<T extends any> = T extends readonly any[] ? T['length'] : never
Exclude
实现内置的Exclude
从T中排除可分配给U的那些类型
T为联合类型的时候,会进行拆分 比如 “a” | “b” | “c”, “a” 会拆分为 a extends a,b extends a,c extends a
type MyExclude<T, U> = T extends U ? never : T/* _____________ 测试用例 _____________ */import { Equal, Expect } from '@type-challenges/utils'type cases = [Expect<Equal<MyExclude<"a" | "b" | "c", "a">, Exclude<"a" | "b" | "c", "a">>>,Expect<Equal<MyExclude<"a" | "b" | "c", "a" | "b">, Exclude<"a" | "b" | "c", "a" | "b">>>,Expect<Equal<MyExclude<string | number | (() => void), Function>, Exclude<string | number | (() => void), Function>>>,]
Awaited
假如我们有一个 Promise 对象,这个 Promise 对象会返回一个类型。在 TS 中,我们用 Promise
比如:Promise<ExampleType>,请你返回 ExampleType 类型。
/* _____________ 你的代码 _____________ */type Awaited<S extends unknown> = S extends Promise<infer Y > ? Y : Stype MyAwaited<T extends Promise<unknown>> = T extends Promise<infer U> ? Awaited<U> : T/* _____________ 测试用例 _____________ */import type { 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
If
Implement a utils If which accepts condition C, a truthy return type T, and a falsy return type F. C is expected to be either true or false while T and F can be any type.
For example:
type A = If<true, 'a', 'b'> // expected to be 'a'type B = If<false, 'a', 'b'> // expected to be 'b'
solutions:
type If<T, U, R> = T extends boolean ? ( T extends true ? U : R ) : never/* _____________ Test Cases _____________ */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-errortype error = If<null, 'a', 'b'>
type Concat<T extends unknown[], U extends unknown[]> = [...T,...U]type a = Concat<[], []>type b = Concat<[], [1]>type c = Concat<[1, 2], [3, 4]>type d = Concat<['1', 2, '3'], [false, boolean, '4']>
type Required1<T> = {[P in keyof T]-?: T[P];};
/* _____________ 你的代码 _____________ */type Includes<T extends readonly unknown[], U> = T extends [infer Head, ...infer Rest]? Equal<Head, U> extends true ? true : Includes<Rest, U>: false/* _____________ 测试用例 _____________ */import type { Equal, Expect } from '@type-challenges/utils'type cases = [Expect<Equal<Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana'], 'Kars'>, true>>,Expect<Equal<Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana'], 'Dio'>, false>>,Expect<Equal<Includes<[1, 2, 3, 5, 6, 7], 7>, true>>,Expect<Equal<Includes<[1, 2, 3, 5, 6, 7], 4>, false>>,Expect<Equal<Includes<[1, 2, 3], 2>, true>>,Expect<Equal<Includes<[1, 2, 3], 1>, true>>,Expect<Equal<Includes<[{}], { a: 'A' }>, false>>,Expect<Equal<Includes<[boolean, 2, 3, 5, 6, 7], false>, false>>,Expect<Equal<Includes<[true, 2, 3, 5, 6, 7], boolean>, false>>,Expect<Equal<Includes<[false, 2, 3, 5, 6, 7], false>, true>>,Expect<Equal<Includes<[{ a: 'A' }], { readonly a: 'A' }>, false>>,Expect<Equal<Includes<[{ readonly a: 'A' }], { a: 'A' }>, false>>,Expect<Equal<Includes<[1], 1 | 2>, false>>,Expect<Equal<Includes<[1 | 2], 1>, false>>,Expect<Equal<Includes<[null], undefined>, false>>,Expect<Equal<Includes<[undefined], null>, false>>,]
type MyOmit<T, K extends keyof T> = { [P in keyof T as P extends K ? never : P]: T[P] }
/* _____________ 你的代码 _____________ */type Last<T extends any[]> = [any , ...T][T['length']]/* _____________ 测试用例 _____________ */import type { Equal, Expect } from '@type-challenges/utils'type cases = [Expect<Equal<Last<[3, 2, 1]>, 1>>,Expect<Equal<Last<[() => 123, { a: string }]>, { a: string }>>,]
