ts体操训练
1 实现pick
type MyPick<T, K extends keyof T> = {[P in K]: T[P]
}
2 实现readonly
让interface中所有属性变为可读
type MyReadonly<T> = {readonly [K in keyof T]: T[K]
}
3 TupleToObject
将元组类型转换为对象类型
type tupleToObject<T extends any[]> ={[k in T[number]]: k
}
4 取出数组的第一项
type First<T extends any[]> = T extends []? never: T[0]T["length"] extends 0 ? never : T[0]T[0] extends T[number]? never: T[0]T extends [ infer First, ...infer Rest]? First : never
5 实现Exclude
type MyExclude<T,U> = T extends U? never:T
6 实现includes
type includes<T extends readonly any[], U> = T extends [infer First, ...infer Rest] ? Equal<First,U> extends true ? true : inlcudes<Rest, U> : false
7 实现ReturnType
type MyReturnType<T> = T extends (...args:any) => infer R ? R : never
8 构造链式对象
//例子
{name: '123',age: {same: true }
}type Chainable<T = {}> = {option: <K extends string, V>(key: K extends T ? V extends T[K]? never : K : K, value: V) => Chainable<Omit<T,K> & Record<K, V>>get: () => T
}
9 取数组最后一项
type Last<T extends any[]> = T extends [...infer Rest, infer L] ? L : never
10 去除字符串左边的空白
type Space = ' ' | '\\n' | '\\t'type TrimLeft<S extends string> = S extends `${Space}${infer R}` ? TrimLeft<R> : S
11 将首字母大写
type Capitalize<S extends string> = S extends `${infer x}${infer Rest}` ? `${UpperCase<X>}${Rest}` : S
12 替换匹配的第一个元素
type Replace<S extends string, From extends string, To extends string> = From extends ''? S : S extends `${infer V}${From}${infer R}` ? `${V}${To}${R}` : S
13 向函数中添加参数
type AppendArguments<Fn,A> = Fn extends (...args: infer R) => infer T ? (...args:[...R, A]) => T : never
14 联合类型的全排列
type Permutation<T,K=T> = [T] extends [never] ? [] : K extends K ? [K, ...Permutation<Exclude<T,K>>] : never
15 字符串的长度
type LengthOfString<S extends string, T extends string[] = []> = S extends `${infer L}${infer R}` ? LengthOfString<R,[...T,R]> : T['length']
16 数组扁平化
type Flatten<T extends any[], U extends any[] = []> = T extends [infer L, ...infer Rest] ? L extends any[] ? Flatten<[...L,...Rest],U> : Flatten<[...Rest],[...U,L]> : U
17 向对象中添加元素
需要限定key的范围,对象的键名应为字符串或数字
type AddToObject<T,U extends keyof any,V> = {[K in keyof T | U] : K extends keyof T? T[K]:V
}