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<KV>>
	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
}

18

你可能感兴趣的:(typescript)