学习索引类型 首先要了解keyof(索引查询) Tk 和泛型约束
就是用来获取某个类型的所有键(键值对的那个键).
interface IPerson { name: string; age: number; } type Test = keyof IPerson; //'name'|"age"
这就相当于获得了IPerson里面的键也就是 是name和age。
就是获取接口T的K属性所代表的类型.
interface IPerson { name: string; age: number; } let type1: IPerson['name'] let type2: IPerson['age']
这样输出的就是string和age了
索引类型就是从对象中抽取一些属性的值 然后拼接成数组
const userInfo = { name: 'lin', age: '18', } function getValues(userInfo: any, keys: string[]) { return keys.map(key => userInfo[key]) } // 抽取指定属性的值 console.log(getValues(userInfo, ['name','age'])) // ['lin', '18'] // 抽取obj中没有的属性: console.log(getValues(userInfo, ['sex','outlook'])) // [undefined, undefined]
这个代码的意思就是 定义了一个对象和一个函数
这个函数得两个形参 第一个是任意类型的userInfo对象 第二个就是字符串类型的数组
通过对第二个形参输入的值遍历去寻找到userInfo中相同的属性的值打印出来
即使userinfo中没有这个属性也不会报错 只会输出undefind
const userInfo = { name: 'lin', age: '18', function getValues(userInfo: T, keys: K[]): T[K][] { return keys.map(key => userInfo[key]) }
这个代码的意思是 定义了一个函数 他是有两种可能的类型 T 和 k
T是用来约束userinfo的 k是用来约束keys的
而K泛型继承了 userinfo的属性
所以当我们要调用这个函数时 形参需要输入的属性名是得符合userinfo中的两个属性名 否则就会报错
TS允许将一个类型映射成另外一个类型
in操作符,用来对联合类型实现遍历。
type Person = "name" | "school" | "major" type Obj = { [p in Person]: string }
Partial
interface IPerson { name:string age:number } let P1: IPerson = { name:'lin', age:18 }
使用了IPerson接口,就一定要传name和age属性。
使用 Partial
改造一下,就可以变成可选属性,
interface IPerson { name:string age:number } type IPartial = Partiallet p1: IPartial = {}
Parital 原理
Parital 的实现用到了in和keyof
type Partial= { [P in keyof T]?: T[P] }
[P in keyof T]遍历
T 上的所有属性
?:设置为属性为可选的
T[P]`设置类型为原来的类型
和Partial几乎完全一样
Readonly
/** * Make all properties in T readonly */ type Readonly= { readonly [P in keyof T]: T[P] }
[P in keyof T]遍历
T`上的所有属性
readonly`设置为属性为可选的
T[P]`设置类型为原来的类型
Pick用于抽取对象子集,挑选一组属性并组成一个新的类型
interface IPerson { name:string age:number sex:string } type IPick = Pick let p1:IPick = { name:'lin', age:18 }
这样就把name和age从IPerson中抽取出来。
/** * Construct a type with a set of properties K of type T */ type Record= { [P in K]: T }
Record映射类型有两个参数:
第一个参数可以传入继承于uany的任何值。
第二个参数,作为新创建对象的值,被传入。
Exclude和Extrcat的实现就用到了条件类型。
/** * Exclude from T those types that are assignable to U */ type Exclude= T extends U ? never : T
never表示一个不存在的类型
never与其他类型的联合后,为其他类型
type Test = string | number | never
Extract
type Test = Extract<'key1' | 'key2', 'key1'> /** * Extract from T those types that are assignable to U */ type Extract= T extends U ? T : never
为了方便开发者使用, TypeScript 内置了一些常用的工具类型。
上文介绍的索引类型、映射类型和条件类型都是工具类型。
Omit
interface IPerson { name:string age:number } type IOmit = Omit
这样就剔除了 IPerson 上的 age 属性。
他和pick有点相反 它的原理
type Omit= Pick >
NonNullable
用来过滤类型中的 null 及 undefined 类型。
type T0 = NonNullable; // string | number type T1 = NonNullable ; // string[]
原理
type NonNullable= T extends null | undefined ?never : T
never 表示一个不存在的类型
never与其他类型的联合后,为其他类型
Parameters获取函数的参数类型,将每个参数类型放在一个元祖中。
type T1 = Parameters<() => string> // [] type T2 = Parameters<(arg: string) => void> // [string] type T3 = Parameters<(arg1: string, arg2: number) => void> // [arg1: string, arg2: number]
Parameters原理
type Parametersany> = T extends (...args: infer P) => any ? P : never
在条件类型语句中,可以用 infer
声明一个类型变量并且对它进行使用。
Parameters首先约束参数
T`必须是个函数类型
判断T
是否是函数类型,如果是则使用infer P
暂时存一下函数的参数类型,后面的语句直接用 P 即可得到这个类型并返回,否则就返回never
4.ReturnType
ReturnType获取函数的返回值类型
type T0 = ReturnType<() => string> // string type T1 = ReturnType<(s: string) => void> // void
ReturnType原理
/** * Obtain the return type of a function type */ type ReturnTypeany> = T extends (...args: any) => infer R ? R : any
懂了 Parameters,也就懂了 ReturnType,
ReturnType
首先约束参数T
必须是个函数类型
判断T
是否是函数类型,如果是则使用infer R
暂时存一下函数的返回值类型,后面的语句直接用 R 即可得到这个类型并返回,否则就返回any