最近有了面试的打算,所以抽空整理了一些高难度的内容,有兴趣的小伙伴可以跟我一起慢慢过一遍,一定要要自己手写一遍,不会了在来这里参考!
If
工具类型type If<C extends boolean, T, F> = C extends true ? T : F;
type A = If<true, 'yes', 'no'> // 'yes'
type B = If<false, 1, 2> // 2
Concat
:连接两个数组type Concat<T extends any[], U extends any[]> = [...T, ...U];
type R = Concat<[1, 2], [3, 4]> // [1, 2, 3, 4]
Includes
:判断是否包含type Equal<X, Y> =
(<T>() => T extends X ? 1 : 2) extends
(<T>() => T extends Y ? 1 : 2) ? true : false;
typeIncludes<Textendsreadonlyany[], U> =
Textends [inferF, ...inferR]
? Equal<F, U> extendstrue ? true : Includes<R, U>
: false;
type R = Includes<['a', 'b', 'c'], 'a'> // true
type R2 = Includes<[1, 2, 3], 4> // false
Push
type Push<T extends any[], U> = [...T, U];
type R = Push<[1, 2], 3> // [1, 2, 3]
Unshift
type Unshift<T extends any[], U> = [U, ...T];
type R = Unshift<[2, 3], 1> // [1, 2, 3]
Length
type Length<T extends readonly any[]> = T['length'];
type R = Length<[1, 2, 3]> // 3
Pop
type Pop<T extends any[]> = T extends [...infer R, any] ? R : never;
type R = Pop<[1, 2, 3]> // [1, 2]
Shift
type Shift<T extends any[]> = T extends [any, ...infer R] ? R : never;
type R = Shift<[1, 2, 3]> // [2, 3]
TupleToUnion
type TupleToUnion<T extends any[]> = T[number];
type R = TupleToUnion<['a', 'b', 'c']> // 'a' | 'b' | 'c'
Last
type Last<T extends any[]> = T extends [...any[], infer L] ? L : never;
type R = Last<[1, 2, 3]> // 3
Append
type Append<T extends any[], U> = [...T, U];
type R = Append<[1, 2], 3> // [1, 2, 3]
StartsWith
type StartsWith<S extends string, P extends string> =
S extends `${P}${string}` ? true : false;
type R = StartsWith<'typescript', 'type'> // true
TrimLeft
type TrimLeft<S extends string> = S extends ` ${infer R}` ? TrimLeft<R> : S;
type R = TrimLeft<' hello'> // 'hello'
TrimRight
type TrimRight<S extends string> = S extends `${infer R} ` ? TrimRight<R> : S;
type R = TrimRight<'hello '> // 'hello'
Trim
type Trim<S extends string> = TrimLeft<TrimRight<S>>;
type R = Trim<' hello '> // 'hello'
Replace
type Replace<S extends string, From extends string, To extends string> =
S extends `${infer L}${From}${infer R}` ? `${L}${To}${R}` : S;
type R = Replace<'hello world', 'world', 'TS'> // 'hello TS'
ReplaceAll
type ReplaceAll<S extends string, From extends string, To extends string> =
S extends `${infer L}${From}${infer R}` ? ReplaceAll<`${L}${To}${R}`, From, To> : S;
type R = ReplaceAll<'a_a_a', '_', '-'> // 'a-a-a'
CapitalizeWords
type CapitalizeWords<S extends string> =
S extends `${infer Head} ${infer Tail}`
? `${Capitalize<Head>} ${CapitalizeWords<Tail>}`
: Capitalize<S>;
type R = CapitalizeWords<'hello world ts'> // 'Hello World Ts'
ReverseTuple
type Reverse<T extends any[], R extends any[] = []> =
T extends [infer F, ...infer Rest] ? Reverse<Rest, [F, ...R]> : R;
type R = Reverse<[1, 2, 3]> // [3, 2, 1]
Flatten
type Flatten<T extends any[]> =
T extends [infer F, ...infer R]
? [...(F extends any[] ? Flatten<F> : [F]), ...Flatten<R>]
: [];
type R = Flatten<[1, [2, 3], [[4]]]> // [1, 2, 3, 4]
DeepReadonly
type DeepReadonly<T> = {
readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];
};
type Obj = { a: { b: { c: string } } };
type R = DeepReadonly<Obj>;
// { readonly a: { readonly b: { readonly c: string } } }
UnionToIntersection
type UnionToIntersection<U> =
(U extends any ? (k: U) => void : never) extends
(k: infer I) => void ? I : never;
type R = UnionToIntersection<{a: 1} | {b: 2}> // {a: 1} & {b: 2}
Permutation
type Permutation<T, K = T> =
[T] extends [never] ? [] :
T extends K ? [T, ...Permutation<Exclude<K, T>>] : never;
type R = Permutation<'a' | 'b' | 'c'>
// ['a','b','c'] | ['a','c','b'] | ['b','a','c'] | ...
IsUnion
type IsUnion<T, C = T> =
T extends any ? ([C] extends [T] ? false : true) : never;
type R1 = IsUnion<string | number> // true
type R2 = IsUnion<string> // false
IsNever
type IsNever<T> = [T] extends [never] ? true : false;
type R1 = IsNever<never> // true
type R2 = IsNever<string> // false
IsTuple
type IsTuple<T> =
T extends readonly any[] ? number extends T['length'] ? false : true : false;
type R1 = IsTuple<[1, 2]> // true
type R2 = IsTuple<number[]> // false
Get<T, K>
类似 lodash.gettype Get<T, K extends string> =
K extends `${infer F}.${infer R}`
? F extends keyof T ? Get<T[F], R> : never
: K extends keyof T ? T[K] : never;
type Obj = { a: { b: { c: string } } };
type R = Get<Obj, 'a.b.c'> // string
PickByValue
type PickByValue<T, V> = {
[K in keyof T as T[K] extends V ? K : never]: T[K];
};
type Obj = { name: string; age: number; gender: string };
type R = PickByValue<Obj, string> // { name: string; gender: string }
我也是边学边实现的,如果有啥错误的地方欢迎指正!
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有