TypeScript 体操,从进阶到放弃!
前言
最近有了面试的打算,所以抽空整理了一些高难度的内容,有兴趣的小伙伴可以跟我一起慢慢过一遍,一定要要自己手写一遍,不会了在来这里参考!
正文
1. If
工具类型
代码语言:javascript代码运行次数:0运行复制type If<C extends boolean, T, F> = C extends true ? T : F;
代码语言:javascript代码运行次数:0运行复制type A = If<true, 'yes', 'no'> // 'yes'
type B = If<false, 1, 2> // 2
2. Concat
:连接两个数组
代码语言:javascript代码运行次数:0运行复制type Concat<T extends any[], U extends any[]> = [...T, ...U];
代码语言:javascript代码运行次数:0运行复制type R = Concat<[1, 2], [3, 4]> // [1, 2, 3, 4]
3. Includes
:判断是否包含
代码语言:javascript代码运行次数:0运行复制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;
代码语言:javascript代码运行次数:0运行复制type R = Includes<['a', 'b', 'c'], 'a'> // true
type R2 = Includes<[1, 2, 3], 4> // false
4. Push
代码语言:javascript代码运行次数:0运行复制type Push<T extends any[], U> = [...T, U];
代码语言:javascript代码运行次数:0运行复制type R = Push<[1, 2], 3> // [1, 2, 3]
5. Unshift
代码语言:javascript代码运行次数:0运行复制type Unshift<T extends any[], U> = [U, ...T];
代码语言:javascript代码运行次数:0运行复制type R = Unshift<[2, 3], 1> // [1, 2, 3]
6. Length
代码语言:javascript代码运行次数:0运行复制type Length<T extends readonly any[]> = T['length'];
代码语言:javascript代码运行次数:0运行复制type R = Length<[1, 2, 3]> // 3
7. Pop
代码语言:javascript代码运行次数:0运行复制type Pop<T extends any[]> = T extends [...infer R, any] ? R : never;
代码语言:javascript代码运行次数:0运行复制type R = Pop<[1, 2, 3]> // [1, 2]
8. Shift
代码语言:javascript代码运行次数:0运行复制type Shift<T extends any[]> = T extends [any, ...infer R] ? R : never;
代码语言:javascript代码运行次数:0运行复制type R = Shift<[1, 2, 3]> // [2, 3]
9. TupleToUnion
代码语言:javascript代码运行次数:0运行复制type TupleToUnion<T extends any[]> = T[number];
代码语言:javascript代码运行次数:0运行复制type R = TupleToUnion<['a', 'b', 'c']> // 'a' | 'b' | 'c'
10. Last
代码语言:javascript代码运行次数:0运行复制type Last<T extends any[]> = T extends [...any[], infer L] ? L : never;
代码语言:javascript代码运行次数:0运行复制type R = Last<[1, 2, 3]> // 3
11. Append
代码语言:javascript代码运行次数:0运行复制type Append<T extends any[], U> = [...T, U];
代码语言:javascript代码运行次数:0运行复制type R = Append<[1, 2], 3> // [1, 2, 3]
12. StartsWith
代码语言:javascript代码运行次数:0运行复制type StartsWith<S extends string, P extends string> =
S extends `${P}${string}` ? true : false;
代码语言:javascript代码运行次数:0运行复制type R = StartsWith<'typescript', 'type'> // true
13. TrimLeft
代码语言:javascript代码运行次数:0运行复制type TrimLeft<S extends string> = S extends ` ${infer R}` ? TrimLeft<R> : S;
代码语言:javascript代码运行次数:0运行复制type R = TrimLeft<' hello'> // 'hello'
14. TrimRight
代码语言:javascript代码运行次数:0运行复制type TrimRight<S extends string> = S extends `${infer R} ` ? TrimRight<R> : S;
代码语言:javascript代码运行次数:0运行复制type R = TrimRight<'hello '> // 'hello'
15. Trim
代码语言:javascript代码运行次数:0运行复制type Trim<S extends string> = TrimLeft<TrimRight<S>>;
代码语言:javascript代码运行次数:0运行复制type R = Trim<' hello '> // 'hello'
16. Replace
代码语言:javascript代码运行次数:0运行复制type Replace<S extends string, From extends string, To extends string> =
S extends `${infer L}${From}${infer R}` ? `${L}${To}${R}` : S;
代码语言:javascript代码运行次数:0运行复制type R = Replace<'hello world', 'world', 'TS'> // 'hello TS'
17. ReplaceAll
代码语言:javascript代码运行次数:0运行复制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;
代码语言:javascript代码运行次数:0运行复制type R = ReplaceAll<'a_a_a', '_', '-'> // 'a-a-a'
18. CapitalizeWords
代码语言:javascript代码运行次数:0运行复制type CapitalizeWords<S extends string> =
S extends `${infer Head} ${infer Tail}`
? `${Capitalize<Head>} ${CapitalizeWords<Tail>}`
: Capitalize<S>;
代码语言:javascript代码运行次数:0运行复制type R = CapitalizeWords<'hello world ts'> // 'Hello World Ts'
19. ReverseTuple
代码语言:javascript代码运行次数:0运行复制type Reverse<T extends any[], R extends any[] = []> =
T extends [infer F, ...infer Rest] ? Reverse<Rest, [F, ...R]> : R;
代码语言:javascript代码运行次数:0运行复制type R = Reverse<[1, 2, 3]> // [3, 2, 1]
20. Flatten
代码语言:javascript代码运行次数:0运行复制type Flatten<T extends any[]> =
T extends [infer F, ...infer R]
? [...(F extends any[] ? Flatten<F> : [F]), ...Flatten<R>]
: [];
代码语言:javascript代码运行次数:0运行复制type R = Flatten<[1, [2, 3], [[4]]]> // [1, 2, 3, 4]
21. DeepReadonly
代码语言:javascript代码运行次数:0运行复制type DeepReadonly<T> = {
readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];
};
代码语言:javascript代码运行次数:0运行复制type Obj = { a: { b: { c: string } } };
type R = DeepReadonly<Obj>;
// { readonly a: { readonly b: { readonly c: string } } }
22. UnionToIntersection
代码语言:javascript代码运行次数:0运行复制type UnionToIntersection<U> =
(U extends any ? (k: U) => void : never) extends
(k: infer I) => void ? I : never;
代码语言:javascript代码运行次数:0运行复制type R = UnionToIntersection<{a: 1} | {b: 2}> // {a: 1} & {b: 2}
23. Permutation
代码语言:javascript代码运行次数:0运行复制type Permutation<T, K = T> =
[T] extends [never] ? [] :
T extends K ? [T, ...Permutation<Exclude<K, T>>] : never;
代码语言:javascript代码运行次数:0运行复制type R = Permutation<'a' | 'b' | 'c'>
// ['a','b','c'] | ['a','c','b'] | ['b','a','c'] | ...
24. IsUnion
代码语言:javascript代码运行次数:0运行复制type IsUnion<T, C = T> =
T extends any ? ([C] extends [T] ? false : true) : never;
代码语言:javascript代码运行次数:0运行复制type R1 = IsUnion<string | number> // true
type R2 = IsUnion<string> // false
25. IsNever
代码语言:javascript代码运行次数:0运行复制type IsNever<T> = [T] extends [never] ? true : false;
代码语言:javascript代码运行次数:0运行复制type R1 = IsNever<never> // true
type R2 = IsNever<string> // false
26. IsTuple
代码语言:javascript代码运行次数:0运行复制type IsTuple<T> =
T extends readonly any[] ? number extends T['length'] ? false : true : false;
代码语言:javascript代码运行次数:0运行复制type R1 = IsTuple<[1, 2]> // true
type R2 = IsTuple<number[]> // false
27. Get<T, K>
类似 lodash.get
代码语言:javascript代码运行次数:0运行复制type 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;
代码语言:javascript代码运行次数:0运行复制type Obj = { a: { b: { c: string } } };
type R = Get<Obj, 'a.b.c'> // string
28. PickByValue
代码语言:javascript代码运行次数:0运行复制type PickByValue<T, V> = {
[K in keyof T as T[K] extends V ? K : never]: T[K];
};
代码语言:javascript代码运行次数:0运行复制type Obj = { name: string; age: number; gender: string };
type R = PickByValue<Obj, string> // { name: string; gender: string }
最后
我也是边学边实现的,如果有啥错误的地方欢迎指正!
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。原始发表:2025-04-28,如有侵权请联系 cloudcommunity@tencent 删除面试typescriptextendsstring工具类
发布评论