TS类型体操题库 只记录TS类型体操刷题答案,不讲解
tstype MyPick<T, K extends keyof T> = {
[P in K]: T[P]
}
tstype MyReadonly<T> = {
readonly [P in keyof T]: T[P]
}
tstype TupleToObject<T extends readonly (number | string)[]> = {
[P in T[number]]: P
}
tstype First<T extends any[]>
= T extends [infer First, ...infer Rest]
? First
:never
tstype Length<T extends readonly any[]>
= T['length'];
tstype MyExclude<T, U> = T extends U ? never: T
tstype If<C extends boolean, T, F> = C extends true ? T : F
tstype 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;
tstype 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];
tstype 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;
tstype Push<T extends any[], U>
= [...T, U]
tstype Unshift<T extends any[], U> = [U, ...T]
tstype MyParameters<T extends (...args: any[]) => any>
= T extends (...args: infer R) => any
? R
: never
tstype MyReturnType<T extends (...args: any) => any>
= T extends (...args: any) => infer R
? R
: never
tstype MyOmit<T, K extends keyof T> = {
[P in Exclude<keyof T, K>]: T[P]
}
tstype 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]
}
tstype 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]
}
tstype 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]
tstype 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
}
tstype Last<T extends any[]>
= T['length'] extends 0
? never
: T extends [...infer R, infer L]
? L
: T[0]
tstype Pop<T extends any[]>
= T['length'] extends 0
? T
: T extends [...infer L, infer R]
? L
: never;
Awaited
tstype 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]>;
}>
tstype LookUp<T, P extends string> = {
[K in P]: T extends {type: P} ? T : never
}[P]
tstype TrimLeft<S extends string>
= S extends `${infer L}${infer Rest}`
? L extends ' ' | '\n' | '\t'
? TrimLeft<Rest>
: S
: S;
tstypeSpace = ' ' | '\n' | '\t';
type Trim<S extends string>
= S extends ( `${Space}${infer Rest}` | `${infer Rest}${Space}`)
? Trim<Rest> : S
tstype MyCapitalize<S extends string> = S extends `${infer First}${infer Rest}` ? `${Uppercase<First>}${Rest}` : '';
tstype 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
tstype 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
tstype AppendArgument<Fn extends (...args: any[]) => any, A>
= Fn extends (...args: infer Args) => infer R
? (...args: [...Args, A]) => R
: Fn
tstype Permutation<T, K=T> =
[T] extends [never]
? []
: K extends K
? [K, ...Permutation<Exclude<T, K>>]
: never
tstype 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]]>;
tstype 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]]
tstype AppendToObject<T extends object, U extends string, V> = {
[P in keyof T | U]: P extends keyof T ? T[P] : V
}
tstype Absolute<T extends number | string | bigint>
= `${T}` extends `-${infer U}` ? U: `${T}`
tstype StringToUnion<T extends string, U = never>
= T extends ''
? U
: T extends `${infer L}${infer R}`
? StringToUnion<R, U | L>
: U | T[0];
tstype 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;
}
tstype KebabCase<S> = S extends `${infer L}${infer R}`
? R extends Uncapitalize<R>
? `${Uncapitalize<L>}${KebabCase<R>}`
: `${Uncapitalize<L>}-${KebabCase<R>}`
: S
tstype 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
}
tstype 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
tstype IsNever<T> = [T] extends [never] ? true: false
tstype 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
tstype 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
tstype RemoveIndexSignature<T> = {
[
k in keyof T as string extends k ? never : number extends k? never : symbol extends k ? never : k
]: T[k]
}
tstype 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>];
tstype DropChar<S, C extends string>
= S extends `${infer L}${infer Rest}`
? L extends C
? `${DropChar<Rest, C>}`
: `${L}${DropChar<Rest, C>}`
: ''
这一题太奇葩了,感觉学习意义不大
ts
tstype PickByType<T, U> = {
[
P in keyof T as P extends any
? T[P] extends U
? P
: never
: never
]: T[P]
}
tstype 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
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
tstype 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]
}>
tstype Mutable<T extends object> = {
-readonly [P in keyof T]: T[P]
}
tstype 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>
tstype 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]
tstype Shift<T extends any[]>
= T['length'] extends 0 ? [] :
T extends [infer F, ...infer Rest]
? Rest
: []
tstype 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>
tstype 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]];
tstype 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
这一题比较难, 全面考察了数组变换和加减运算
tstype 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>]
: []
tstype 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>}`
tstype InorderTraversal<
T extends TreeNode | null,
NT extends TreeNode = NonNullable<T>
> = T extends null ? [] :
[
...InorderTraversal<NT['left']>,
NT['val'],
...InorderTraversal<NT['right']>
]
tstype 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
}
tstype 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]>
注: 未跑通全部用例
tstype 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 许可协议。转载请注明出处!