1978・Percentage Parser
知识点
- 判断是否为数字字符串
T extends `${number}`
另一种思路
2070・Drop Char
2257・MinusOne
一般解法只能计算不超过1000的数字
type NewArrByLeng<N extends number, A extends any[] = []> = A['length'] extends N ? A : NewArrByLeng<N, [...A, 1]>
type MinusOne<T extends number, A extends any[] = NewArrByLeng<T>> = A extends [infer F, ...infer R] ? R['length'] : 0
2595・PickByType
type PickByType<T, U> = {
[k in keyof T as T[k] extends U ? k : never]: T[k]
}
2688・StartsWith
type StartsWith<T extends string, U extends string> = T extends `${U}${infer R}` ? true : false
2693・EndsWith
type EndsWith<T extends string, U extends string> = T extends `${infer R}${U}` ? true : false
2757・PartialByKeys
知识点:
- 快速复制一个对象
Omit<Obj, never>
type CloneObj<T> = {
[k in keyof T]: T[k]
}
type PartialByKeys<T, K extends any = keyof T> = CloneObj<{
[k in keyof T as k extends K ? never : k]: T[k]
} & {
[k in K as k extends keyof T ? k : never]?: k extends keyof T ? T[k] : never
}>
// 精简版
type PartialByKeys<T, K extends keyof any = string> = Omit<{ [k in K & keyof T]?: T[k] } & Omit<T, K>, never>;
2759・RequiredByKeys
type RequiredByKeys<T, K extends string | number | symbol = keyof T> = Omit<Omit<T, K> & Required<Pick<T, K extends keyof T ? K : never>>, never>
2793・Mutable
type Mutable<T> = {
-readonly[k in keyof T]: T[k]
}
2852・OmitByType
type OmitByType<T, U> = {
[k in keyof T as T[k] extends U ? never : k]: T[k]
}
2946・ObjectEntries
知识点:
去除联合类型中的undefined type RemoveUndefined<T> = [T] extends [undefined] ? T: Exclude<T, undefined>;
type RemoveUndefined<T> = [T] extends [undefined] ? T: Exclude<T, undefined>;
type ObjectEntries<T, P extends keyof T = keyof T> = P extends any ? [P, RemoveUndefined<T[P]>] : never
// 另一种产生联合类型的方式
type ObjectEntries<T> = {
[K in keyof T]-?: [K, RemoveUndefined<T[K]>];
}[keyof T]
3062・Shift
type Shift<T> = T extends [infer F, ...infer R] ? [...R] : T
3188・Tuple to Nested Object
type TupleToNestedObject<T, U> = T extends readonly [infer F, ...infer R] ? F extends string ? {
[k in F]: R extends never ? U : TupleToNestedObject<R, U>
} : U : U
// 更加精简的写法。不需要判断F是否是string,而是直接&string
type TupleToNestedObject<T, U> = T extends readonly [infer F, ...infer R] ? {
[k in F & string]: R extends never ? U : TupleToNestedObject<R, U>
} : U
3192・Reverse
type Reverse<T, L extends any[] = []> = T extends [infer F, ...infer R] ? Reverse<R, [ F, ...L]> : L
3196・Flip Arguments
type Reverse<T, L extends any[] = []> = T extends [infer F, ...infer R] ? Reverse<R, [ F, ...L]> : L
type FlipArguments<T> = T extends (...a: infer P) => infer R ? (...b: Reverse<P>) => R : never
3243・FlattenDepth
这种思路是递归的时候带上最终的值
type FlattenDepth<T extends any[], N extends number = 1, H extends any[] = [], V extends any[] = []> =
H['length'] extends N
? T extends any[] ? [...V, ...T] : [...V, T]
: T extends [infer F, ...infer R]
? FlattenDepth<R, N, H, [...V, ...(F extends any[] ? FlattenDepth<F, N, [...H, 1], []> : [F])]>
: [...V]
这种思路是直接构造出最终的结构,FlattenDepth返回结果就是T的扁平化结构(推荐)
type FlattenDepth<T extends any[], N extends number = 1, H extends any[] = []> = T extends [infer F, ...infer R]
? H['length'] extends N ? T : F extends any[]
? [...FlattenDepth<F, N, [...H, 1]>, ...FlattenDepth<R, N, H>]
: [F, ...FlattenDepth<R, N, H>]
: T
3326・BEM style string
知识点
- 泛型(T)如果是never,内部直接使用 T extends xx 会直接返回never
- 除了联合类型通过extends可以触发遍历逻辑外,字符串模板也可以(第二种实现)
type IsString<T> = [T] extends [never] ? false : T extends string ? true : false
type BEM<B extends string, E extends string[], M extends string[], A extends string = E[number], C extends string = M[number]> =
IsString<A> extends true
? IsString<C> extends true
? `${B}__${A}--${C}`: `${B}__${A}`
: IsString<C> extends true ? `${B}--${C}`
: B
type BEM<B extends string, E extends string[], M extends string[]> = E[number] extends never
? M[number] extends never
? B
: `${B}--${M[number]}`
: M[number] extends never
? `${B}__${E[number]}`
: `${B}__${E[number]}--${M[number]}`
3376・InorderTraversal
在T外层套一层[],避免ts报错死循环
type InorderTraversal<T extends TreeNode | null> = [T] extends [TreeNode] ? [...InorderTraversal<T['left']>, T['val'], ...InorderTraversal<T['right']>] : []
4179・Flip
type Flip<T extends Record<string | number, string | any>> = {
[k in keyof T as `${T[k]}`]: k
}
4182・斐波那契序列
type Fibonacci<T extends number, F extends any[] = [1], S extends any[] = [1], I extends any[] = [1]> = I['length'] extends T
? F['length']
: Fibonacci<T, [...S], [...F,...S], [...I, 1]>
4260・AllCombinations
没做出来,参考答案做的很巧妙
4425・Greater Than
type GreaterThan<T extends number, U extends number, V extends any[] = []> = V['length'] extends T ? false : V['length'] extends U ? true : GreaterThan<T, U, [...V, 1]>
4471・Zip
type Zip<T extends any[], P extends any[] = [], I extends any[] = [], R extends any[] = []> =
T[I['length']] extends undefined ? R :
P[I['length']] extends undefined ? R
: Zip<T, P, [...I, 1], [...R, [T[I['length']], P[I['length']]]]>
简洁版
type Zip<T extends any[], S> = T extends [infer L, ...infer R] ? S extends [infer SL, ...infer SR] ? [[L, SL], ...Zip<R, SR>] : []: []
4484・IsTuple
type IsTuple<T> =[T] extends [never]
? false : T extends readonly any[]
? number extends T['length'] ? false : true : false
4499・Chunk
type Chunk<T, N, R extends any[] = [], L extends any[] = []> = L['length'] extends N
? Chunk<T, N, [...R, L]> : T extends [infer F, ...infer P]
? Chunk<P, N, R, [...L, F]> : L['length'] extends 0 ? R : [...R, L]
优化版本:少一个参数
type Chunk<T extends any[],C extends number,S extends any[] = []> =
S['length'] extends C?
[S,...Chunk<T,C>]
: T extends [infer F,...infer R]?
Chunk<R,C,[...S,F]>
: S['length'] extends 0? []: [S]
4518・Fill
type Fill<
T extends unknown[],
N,
Start extends number = 0,
End extends number = T['length'],
R extends unknown[] = [],
S extends boolean = false
> = T extends [infer F, ...infer L]
? R['length'] extends End ? Fill<L, N, Start, End, [...R, F], false>
: R['length'] extends Start ? Fill<L, N, Start, End, [...R, N], true>
: Fill<L, N, Start, End, [...R, S extends true ? N : F], S> : R
4803・Trim Right
type TrimRight<S extends string> = S extends `${infer Left}${' ' | '\n' | '\t'}` ? TrimRight<Left> : S
5117・去除数组指定元素
type IsIncludes<T extends number | number[], V> = T extends number[] ? V extends T[number] ? true : false : T extends V ? true : false
type Without<T extends any[], U extends number | number[]> = T extends [infer F, ...infer R] ? IsIncludes<U, F> extends true ? Without<R, U> : [F, ...Without<R, U>] : []
5140・Trunc
type Trunc<T extends number | string> = `${T}` extends `${infer R}.${infer N}` ? R : `${T}`
5153・IndexOf
敲重点,如何判断两个值绝对相同
type IsEqual<T, U> = (<V>() => V extends T ? 1 : 0) extends (<V>() => V extends U ? 1 : 0) ? true : false
通过构造两个函数来对比,否则的话类似any这种和其他类型都相等,由此我们可以写出如何判断是否是any类型
type IsAny<T> = (<V>() => V extends any ? 1 : 0) extends (<V>() => V extends T ? 1 : 0) ? true : false
type IndexOf<T extends unknown[], U extends unknown, Count extends 1[] = []> =
T extends [infer First, ...infer Rest] ? (
(<V>() => V extends First ? 1 : 0) extends
(<V>() => V extends U ? 1 : 0) ? (
Count['length']
) : IndexOf<Rest, U, [...Count, 1]>
) : -1
5310・Join
type Join<T extends string[], U extends string> = T extends [infer F extends string, ...infer R extends string[]] ? `${F}${R['length'] extends 0 ? '' : U}${Join<R, U>}` : ''
5317・LastIndexOf
type LastIndexOf<T extends any[], V, I extends any[] = [], A extends number = -1> =
T extends [infer L, ...infer R]
? (<U>() => U extends L ? 1 : 0) extends (<U>() => U extends V ? 1 : 0)
? LastIndexOf<R, V, [...I, 1], I['length']>
: LastIndexOf<R, V, [...I, 1], A>
: A
5360・Unique
Equal上面已经实现过了
type IsIncludes<T extends any[], V> = T extends [infer F, ...infer R] ? Equal<F, V> extends true ? true : IsIncludes<R, V> : false
type Unique<T extends any[], E extends any[] = []> = T extends [infer F, ...infer R] ? IsIncludes<E, F> extends true ? Unique<R, E> : Unique<R, [...E, F]> : E
5821・MapTypes
type Helper<R, V> = R extends { mapFrom: V; mapTo: any } ? R['mapTo'] : never
type MapTypes<T, R extends Record<'mapFrom' | 'mapTo', unknown>> = {
[k in keyof T]: Helper<R, T[k]> extends never ? T[k] : Helper<R, T[k]>
}
稍微换下思路,就可以避免多计算一次
type MapTypes<T, R extends Record<'mapFrom' | 'mapTo', unknown>> = {
[P in keyof T]: T[P] extends R['mapFrom'] ? R extends { mapFrom: T[P] } ? R['mapTo'] : never : T[P]
}
8987・Subsequence
type ConstructTuple<L extends number, R extends unknown[] = []> = R['length'] extends L ? R : ConstructTuple<L, [...R, unknown]>
8640・Number Range
type NumberRange<L extends number, H extends number, R extends number[] = [], P extends any[] = []> =
P['length'] extends H ? R[number] | H
: NumberRange<L, H, P['length'] extends L ? [...R, L] : R['length'] extends 0 ? R : [...R, P['length']], [...P, 1]>
8767・Combination
type Combination<T extends string[], All = T[number], Item = All>
= Item extends infer Item extends string
? Item | `${Item} ${Combination<[], Exclude<All, Item>>}`
: never
8987・Subsequence
type Subsequence<T> = T extends [infer One, ...infer Rest]
? [One] | [...Subsequence<Rest>] | [One, ...Subsequence<Rest>]
: []