2023-06-08
TypeScript
00
请注意,本文编写于 550 天前,最后修改于 317 天前,其中某些信息可能已经过时。

目录

简单
实现Pick
实现Readonly
元组转换为对象
第一个元素
获取元组长度
Exclude
IF
Awaited
Concat
Includes
Push
Unshift
Parameters
中等
获取函数返回类型
Omit
Readonly2
深度Readonly
元组转合集
可串联构造器
最后一个元素
出堆Pop
Promise.all
LookUp
Trim Left
Trim
Capitalize
Replace
ReplaceAll
Append Argument
Permutation
Length Of String
Flatten
Append to object
Absolute
StringToUnion
Merge
KebabCase
Diff
AnyOf
IsNever
IsUnion
ReplaceKeys
Remove Index Signature
PercentageParser
Drop Char
MinusOne
PickByType
StartsWith
EndsWith
PartialByKeys
Mutable
OmitByType
ObjectEntries
Shift
TupleToNestedObject
Reverse
Flip Arguments
FlattenDepth
BEM
InorderTraversal
Flip
Fibonacci
GreaterThan

TS类型体操题库 只记录TS类型体操刷题答案,不讲解

简单

实现Pick

ts
type MyPick<T, K extends keyof T> = { [P in K]: T[P] }

实现Readonly

ts
type MyReadonly<T> = { readonly [P in keyof T]: T[P] }

元组转换为对象

ts
type TupleToObject<T extends readonly (number | string)[]> = { [P in T[number]]: P }

第一个元素

ts
type First<T extends any[]> = T extends [infer First, ...infer Rest] ? First :never

获取元组长度

ts
type Length<T extends readonly any[]> = T['length'];

Exclude

ts
type MyExclude<T, U> = T extends U ? never: T

IF

ts
type If<C extends boolean, T, F> = C extends true ? T : F

Awaited

ts
type Thenable<T> = {then:(onfulfilled: (val: T, ...args: any) => any) => any} type MyAwaited<T extends Thenable<any>> = T extends Thenable<infer R> ? R extends Thenable<any> ? MyAwaited<R> : R : T;

Concat

ts
type Concat<T extends readonly any[], U extends readonly any[]> = U extends [] ? T : U extends [infer First, ...infer Last] ? Concat<[...T, First], Last> : [...T, ...U] // 解法2 type Concat<T extends readonly any[], U extends readonly any[]> = [...T, ...U];

Includes

ts
type Includes<T extends readonly any[], U> = T['length'] extends 0 ? false : T extends [infer First, ...infer Rest] ? Equal<First, U> extends true ? true : Includes<Rest, U> : never;

Push

ts
type Push<T extends any[], U> = [...T, U]

Unshift

ts
type Unshift<T extends any[], U> = [U, ...T]

Parameters

ts
type MyParameters<T extends (...args: any[]) => any> = T extends (...args: infer R) => any ? R : never

中等

获取函数返回类型

ts
type MyReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : never

Omit

ts
type MyOmit<T, K extends keyof T> = { [P in Exclude<keyof T, K>]: T[P] }

Readonly2

ts
type MyReadonly2<T, K extends keyof T = keyof T> = { [P in keyof T as P extends K ? never : P]: T[P] } & { readonly [P in K]: T[P] }

深度Readonly

ts
type DeepReadonly<T extends object> = { readonly [P in keyof T]: T[P] extends object ? T[P] extends (...args: any) => any ? T[P] : DeepReadonly<T[P]> : T[P] }

元组转合集

ts
type TupleToUnion<T extends readonly any[], U extends any = never> = T['length'] extends 0 ? U : T extends [infer First, ...infer Rest] ? TupleToUnion<Rest, U | First> : U | T[0]

可串联构造器

ts
type Chainable<T = {}> = { option<K extends string, V>( key: K extends keyof T ? never: K, value: V, ): Chainable<Omit<T, K> & Record<K, V>> get(): T }

最后一个元素

ts
type Last<T extends any[]> = T['length'] extends 0 ? never : T extends [...infer R, infer L] ? L : T[0]

出堆Pop

ts
type Pop<T extends any[]> = T['length'] extends 0 ? T : T extends [...infer L, infer R] ? L : never;

Promise.all

  • 这一题比较难,还考察了 Awaited
ts
type MyAwaited<T> = T extends { then: (onfulfilled: (args: infer R) => any) => any } ? R extends object ? MyAwaited<R> : R : T declare function PromiseAll<T extends any[]>(values: readonly [...T]): Promise<{ [P in keyof T]: MyAwaited<T[P]>; }>

LookUp

ts
type LookUp<T, P extends string> = { [K in P]: T extends {type: P} ? T : never }[P]

Trim Left

ts
type TrimLeft<S extends string> = S extends `${infer L}${infer Rest}` ? L extends ' ' | '\n' | '\t' ? TrimLeft<Rest> : S : S;

Trim

ts
typeSpace = ' ' | '\n' | '\t'; type Trim<S extends string> = S extends ( `${Space}${infer Rest}` | `${infer Rest}${Space}`) ? Trim<Rest> : S

Capitalize

ts
type MyCapitalize<S extends string> = S extends `${infer First}${infer Rest}` ? `${Uppercase<First>}${Rest}` : '';

Replace

ts
type Replace<S extends string, From extends string, To extends string> = From extends '' ? S : S extends `${From}${infer Rest}` ? `${To}${Rest}` : S extends `${infer L}${From}${infer R}` ? `${L}${To}${R}` : S extends `${infer Rest}${From}` ? `${Rest}${To}` : S

ReplaceAll

ts
type ReplaceAll<S extends string, From extends string, To extends string> = From extends '' ? S : S extends `${From}${infer Rest}` ? `${To}${ReplaceAll<Rest, From, To>}` : S extends `${infer L}${From}${infer R}` ? `${ReplaceAll<L, From, To>}${To}${ReplaceAll<R, From, To>}` : S extends `${infer Rest}${From}` ? `${ReplaceAll<Rest, From, To>}${To}` : S

Append Argument

ts
type AppendArgument<Fn extends (...args: any[]) => any, A> = Fn extends (...args: infer Args) => infer R ? (...args: [...Args, A]) => R : Fn

Permutation

  • 这一题变态难,没搞明白
ts
type Permutation<T, K=T> = [T] extends [never] ? [] : K extends K ? [K, ...Permutation<Exclude<T, K>>] : never

Length Of String

ts
type LengthOfString<S extends string, U extends string[] = []> = S extends '' ? U['length'] : S extends `${infer L}${infer R}` ? LengthOfString<R, [...U, L]> : LengthOfString<'', [...U, S[0]]>;

Flatten

ts
type Flatten<T extends any[], U extends any[] = []> = T['length'] extends 0 ? U : T extends [infer L, ...infer Rest] ? L extends any[] ? Flatten<[...L, ...Rest], U> : Flatten<Rest, [...U, L]> : T[0] extends any[] ? Flatten<T[0], U> : [...U, T[0]]

Append to object

ts
type AppendToObject<T extends object, U extends string, V> = { [P in keyof T | U]: P extends keyof T ? T[P] : V }

Absolute

ts
type Absolute<T extends number | string | bigint> = `${T}` extends `-${infer U}` ? U: `${T}`

StringToUnion

ts
type StringToUnion<T extends string, U = never> = T extends '' ? U : T extends `${infer L}${infer R}` ? StringToUnion<R, U | L> : U | T[0];

Merge

ts
type Merge<F extends object, S extends object> = { [P in keyof S | keyof F]: P extends keyof S ? S[P] : P extends keyof F ? F[P] : never; }

KebabCase

ts
type KebabCase<S> = S extends `${infer L}${infer R}` ? R extends Uncapitalize<R> ? `${Uncapitalize<L>}${KebabCase<R>}` : `${Uncapitalize<L>}-${KebabCase<R>}` : S

Diff

ts
type Diff<O extends object, O1 extends object> = { [P in Exclude<keyof O, keyof O1> | Exclude<keyof O1, keyof O>]: P extends keyof O ? O[P]: P extends keyof O1? O1[P]: never }

AnyOf

ts
type FalseValue = '' | 0 | false | [] | undefined | null | {[key: string]: never}; type AnyOf<T extends readonly any[]> = T["length"] extends 0 ? false: T extends [infer L, ...infer Rest] ? L extends FalseValue ? AnyOf<Rest> : true : T[0] extends FalseValue ? false : true

IsNever

ts
type IsNever<T> = [T] extends [never] ? true: false

IsUnion

ts
type IsUnion<T, U extends T = T> = ( T extends T ? U extends T ? true : unknown // 联合类型 : never ) extends true ? false: true; type A = true extends true ? 1: 0; // 1 type C = never extends true ? 1: 0; // 1 type B = unknown extends true ? 1: 0; // 0

ReplaceKeys

ts
type ReplaceKeys<U, T, Y> = U extends object ? // distributive over union type { [key in keyof U]: key extends T ? key extends keyof Y ? Y[key] : never : U[key] } : never

Remove Index Signature

ts
type RemoveIndexSignature<T> = { [ k in keyof T as string extends k ? never : number extends k? never : symbol extends k ? never : k ]: T[k] }

PercentageParser

ts
type CheckPrefix<T> = T extends ('+' | '-') ? T : never; type CheckSuffix<T> = T extends `${infer Rest}%` ? [Rest, '%'] : [T, '']; type PercentageParser<A extends string> = A extends `${CheckPrefix<infer L>}${infer Rest}` ? [L, ...CheckSuffix<Rest>] : ['', ...CheckSuffix<A>];

Drop Char

ts
type DropChar<S, C extends string> = S extends `${infer L}${infer Rest}` ? L extends C ? `${DropChar<Rest, C>}` : `${L}${DropChar<Rest, C>}` : ''

MinusOne

这一题太奇葩了,感觉学习意义不大

ts

PickByType

ts
type PickByType<T, U> = { [ P in keyof T as P extends any ? T[P] extends U ? P : never : never ]: T[P] }

StartsWith

ts
type StartsWith<T extends string, U extends string> = U extends '' ? true : U extends `${infer L}${infer Rest2}` ? T extends `${L}${infer Rest1}` ? StartsWith<Rest1, Rest2> : false : T extends `${U}${infer Rest1}` ? true : false

EndsWith

ts
// 方式一 借助前面的StartsWith type ReverseStr<T extends string> = T extends `${infer L}${infer R}` ? `${ReverseStr<R>}${L}` : T[0] // T[0] = T type EndsWith<T extends string, U extends string> = StartsWith<ReverseStr<T>, ReverseStr<U>>; // 方式二 type EndsWith<T,b extends string> = T extends `${infer f}${b}`?true:false

PartialByKeys

ts
type IntersectionToObj<T> = { [K in keyof T]: T[K] } type PartialByKeys<T, K extends keyof T = keyof T> = IntersectionToObj<{ [P in Exclude<keyof T, K>]: T[P] } & { [P in K]?: T[P] }>

Mutable

ts
type Mutable<T extends object> = { -readonly [P in keyof T]: T[P] }

OmitByType

ts
type OmitByType<T, U> = { [ P in keyof T as P extends string ? T[P] extends U ? never : P : never ]: T[P] } type AA = OmitByType<Model, boolean>

ObjectEntries

ts
type RemoveUndefined<U> = U extends undefined ? never : U type ObjectEntries<T, U = never> = { // [P in keyof T]-?: [P, T[P]] [P in keyof T]-?: [P, Exclude<keyof T, P> extends never ? T[P] : RemoveUndefined<T[P]>] }[keyof T]

Shift

ts
type Shift<T extends any[]> = T['length'] extends 0 ? [] : T extends [infer F, ...infer Rest] ? Rest : []

TupleToNestedObject

ts
type TupleToNestedObject<T extends string[], U> = T['length'] extends 0 ? U : T extends [infer L, ...infer Rest] ? L extends string ? Rest extends string[] ? Record<L, TupleToNestedObject<Rest, U>> : never : never : Record<T[0], U>

Reverse

ts
type Reverse<T extends any[], Arr extends any[] = []> = T['length'] extends 0 ? Arr : T extends [...infer Rest, infer L] ? Reverse<Rest, [...Arr, L]> : [...Arr, T[0]];

Flip Arguments

ts
type Flip<T extends any[], U extends any[] = []> = T['length'] extends 0 ? U : T extends [infer F, ...infer Rest] ? Flip<Rest, [F, ...U]> : [T[0], ...U] type FlipArguments<T extends (...args: any) => any> = T extends (...args: infer P) => infer Ret ? (...args: Flip<P>) => Ret : never

FlattenDepth

这一题比较难, 全面考察了数组变换和加减运算

ts
type FlattenOnce<T extends any[]> = T extends [infer F, ...infer Rest] ? F extends any[] ? [...F, ...FlattenOnce<Rest>] : [F, ...FlattenOnce<Rest>] : [] type FlattenDepth<T extends any[], S extends number = 1, U extends any[] = [1]> = S extends U['length'] ? FlattenOnce<T> : /* FlattenDepth */ T extends [infer F, ...infer Rest] ? F extends any[] ? [...FlattenDepth<F, S, [...U, 1]>, ...FlattenDepth<Rest, S,U>] : [F, ...FlattenDepth<Rest, S,U>] : []

BEM

ts
type Parse<T extends string[], prefix extends string = '--'> = T['length'] extends 0 ? '' : `${prefix}${T[number]}` type BEM<B extends string, E extends string[], M extends string[]> = `${B}${Parse<E, '__'>}${Parse<M>}`

InorderTraversal

ts
type InorderTraversal< T extends TreeNode | null, NT extends TreeNode = NonNullable<T> > = T extends null ? [] : [ ...InorderTraversal<NT['left']>, NT['val'], ...InorderTraversal<NT['right']> ]

Flip

ts
type Flip<T extends object> = { [ P in keyof T as T[P] extends string ? T[P] : T[P] extends number ? T[P] : T[P] extends boolean ? `${T[P]}` : never ]: P }

Fibonacci

ts
type Fibonacci< T extends number, CurrentIndex extends number[] = [1], Prev extends number[] = [], Current extends number[] = [1] > = CurrentIndex['length'] extends T ? Current['length'] : Fibonacci<T, [...CurrentIndex, 1], Current, [...Prev, ...Current]>

GreaterThan

注: 未跑通全部用例

ts
type GreaterThan< T extends number, U extends number, Arr extends number[] = []> = T extends Arr['length'] ? false : U extends Arr['length'] ? true : GreaterThan<T, U, [...Arr, 1]>

本文作者:郭敬文

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!