1. 对泛型有什么了解?
- 泛型就是引入类型变量来满足类型不确定的需求。
- TS中的泛型就类似于JS中的函数。
- JS中提供了Number,String,Array,Function,Object等构造函数。 TS中提供了Readonly,Partial,Required,Exclude,Extract,Pick,Omit,等泛型
泛型实现细节:
- 泛型约束:使用extends关键字 as关键字
- 获取对象的Key:使用in keyof关键字
- 泛型中的只读readonly 非只读 -readonly
- 泛型中的可选? 非可选 -?
- 泛型中定义类型变量 infer XX
- 泛型中的操作类比 乘法分配率 (A+B)C=AC+BC 乘法中的零 0C=0 联合类型 type ToArray=T extends unknown ? T[]:never type Result=ToArray<string|number> // 泛型中的联合类型操作要分开进行操作,然后再合并到一起 // Result的类型:正确答案:string[]|number[] 错误答案:(string|number)[]
type ResultNever=ToArray // 泛型中,输入是never,输出一定是never // ResultNever的类型:never 错误答案:never[]
2.了解哪些泛型API?
1. Readonly 只读
readonly 的实现很简单,就是在原先的对象的key前面加readonly 关键字.同理,非只读就是把readonly改为-readonly就可以了
interface Todo {
title: string
description: string
}
type MyReadonly<T>={readonly [K in keyof T]:T[K]}
const todo: MyReadonly<Todo> = {
title: "Hey",
description: "foobar"
}
todo.title = "Hello" // Error: cannot reassign a readonly property
todo.description = "barFoo" // Error: cannot reassign a readonly property
2. Partial 可选
type Partial<T>={[Key in keyof T]?:T[Key] }
3. Required 必填
type Required<T>={[Key in keyof T]-?:T[Key] }
4. pick 是指从原对象T中,选出key为K的子集组成的数组
type MyPick<T ,K extends keyof T>={ [Key in K ] : T[Key] }
5.MyParameters 如何获取一个函数的参数类型?
type MyParameters<F extends (...args:any[])=>any>= F extends (...args:infer X)=>any ? X: never
3.数组类型体操
// infer 关键字 显式的声明一个泛型变量. 代表这是一个推断的类型,后边可以取任意名字
数组模式匹配
[...infer Rest, infer Last]
数组有length属性
type A=['a','b','c']
type B=A[length] // TS 元组也自带length属性
// 元组扩展
type A=['a','b','c']
type B=[...A,'last']
type C=[1,2,3]
type D=[...B,...C]
//如何获取数组最后一个元素类型
type Last<T extends unknown[]>=T extends [...unknown[], infer L]?L:never
// infer L 就相当于我自己定义了一个类型变量,然后自己使用
type E=Last<D> // 3
4.字符串类型体操
type A = 'fang'
type B = Capitalize<A> // 首字母大写
type C= Uncapitalize<A> // 首字母小写
type D = Lowercase<A> // 全部小写
type E = Uppercase<A> // 全部大写
type F = `${A}${B}` // 模版字符串
type First<T extends string>= T extends `${infer F}${string}`?F:never
// 获取字符串第一个。 字符串做匹配,会默认前面的只匹配一个字符
type Rust = First<A>
// 字符串转联合类型去重
type StringToUnion<S extends string>=S extends `${infer First}${infer Rest}`? First|StringToUnion<Rest>:never
type ResultUnion =StringToUnion<"xxdnihaoya"> // 联合类型会自动去重
// 字符串转元组
type StringToTuple<S extends string>=S extends `${infer First}${infer Rest}`? [First,...StringToTuple<Rest>]:[]
type Resulttuple=StringToTuple<'xxdnihaoya'>