TS的高级类型

1.索引类型

学习索引类型 首先要了解keyof(索引查询) Tk 和泛型约束

1.keyof索引查询

就是用来获取某个类型的所有键(键值对的那个键).

interface IPerson {
  name: string;
  age: number;
}
 
type Test = keyof IPerson; //'name'|"age"

这就相当于获得了IPerson里面的键也就是 是name和age。

2.T[K] 索引访问

就是获取接口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

3.检查动态属性
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中的两个属性名 否则就会报错

2.映射类型

TS允许将一个类型映射成另外一个类型

1.in

in操作符,用来对联合类型实现遍历。

type Person = "name" | "school" | "major"
 
type Obj =  {
  [p in Person]: string
}
2.Partial

Partial将T的索引属性映射为可选的。

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 = Partial
let p1: IPartial = {}

Parital 原理

Parital 的实现用到了in和keyof

type Partial = {
    [P in keyof T]?: T[P]
}

[P in keyof T]遍历T 上的所有属性

?:设置为属性为可选的

T[P]`设置类型为原来的类型

3.Readonly

和Partial几乎完全一样

Readonly将T的所有属性映射为只读的,例如:

/**
 * Make all properties in T readonly
 */
type Readonly = {
    readonly [P in keyof T]: T[P]
}

[P in keyof T]遍历T`上的所有属性

readonly`设置为属性为可选的

T[P]`设置类型为原来的类型

4.Pick

Pick用于抽取对象子集,挑选一组属性并组成一个新的类型

interface IPerson {
    name:string
    age:number
    sex:string
}
type IPick = Pick
​
let p1:IPick = {
    name:'lin',
    age:18
}

这样就把name和age从IPerson中抽取出来。

5.Record原理
/**
 * Construct a type with a set of properties K of type T
 */
type Record = {
    [P in K]: T
}

Record映射类型有两个参数:

第一个参数可以传入继承于uany的任何值。

第二个参数,作为新创建对象的值,被传入。

3.条件类型

Exclude和Extrcat的实现就用到了条件类型。

1.Exclude

/**
 * Exclude from T those types that are assignable to U
 */
type Exclude = T extends U ? never : T

never表示一个不存在的类型

never与其他类型的联合后,为其他类型

type Test = string | number | never  
2.Extract

Extract提取联合类型T和联合类型U的所有交集.

type Test = Extract<'key1' | 'key2', 'key1'>
​
/**
 * Extract from T those types that are assignable to U
 */
type Extract = T extends U ? T : never
​

4.工具类型

为了方便开发者使用, TypeScript 内置了一些常用的工具类型。

上文介绍的索引类型、映射类型和条件类型都是工具类型。

1.Omit

Omit从类型T中剔除U中的所有属性。

interface IPerson {
    name:string
    age:number
}
type IOmit = Omit

这样就剔除了 IPerson 上的 age 属性。

他和pick有点相反 它的原理

​
type Omit = 
Pick>
​
2.NonNullable

NonNullable 用来过滤类型中的 null 及 undefined 类型。

type T0 = NonNullable; // string | number
type T1 = NonNullable; // string[]

原理

type NonNullable =  T extends null |  undefined ?never : T

never 表示一个不存在的类型

never与其他类型的联合后,为其他类型

3.Parameters

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 Parameters any> = 
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 ReturnType any> = 
T extends (...args: any) => infer R ? R : any

懂了 Parameters,也就懂了 ReturnType,

  • ReturnType首先约束参数T必须是个函数类型

  • 判断T是否是函数类型,如果是则使用infer R暂时存一下函数的返回值类型,后面的语句直接用 R 即可得到这个类型并返回,否则就返回any

你可能感兴趣的:(前端,typescript)