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<T, K extends keyof T>(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>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<IPerson>
let p1: IPartial = {}
Parital 原理

Parital 的实现用到了in和keyof

type Partial<T> = {
    [P in keyof T]?: T[P]
}
[P in keyof T]遍历T 上的所有属性

?:设置为属性为可选的

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

3.Readonly
和Partial几乎完全一样

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

/**
 * Make all properties in T readonly
 */
type Readonly<T> = {
    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<IPerson.'name' | 'age'>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<K extends keyof any, T> = {
    [P in K]: T
}
Record映射类型有两个参数:

第一个参数可以传入继承于uany的任何值。
第二个参数,作为新创建对象的值,被传入。

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

1.Exclude
/**
 * Exclude from T those types that are assignable to U
 */
type Exclude<T, U> = T extends U ? never : T
never表示一个不存在的类型

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

type Test = string | number | never  
2.Extract
Extract<T,U>提取联合类型T和联合类型U的所有交集.

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


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

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

1.Omit
Omit<T,U>从类型T中剔除U中的所有属性。

interface IPerson {
    name:string
    age:number
}
type IOmit = Omit<IPerson,'age'>
这样就剔除了 IPerson 上的 age 属性。

他和pick有点相反 它的原理

type Omit<T, K extends keyof any> = 
Pick<T, Exclude<keyof T, K>>2.NonNullable
NonNullable<T> 用来过滤类型中的 nullundefined 类型。

type T0 = NonNullable<string | number | undefined>; // string | number
type T1 = NonNullable<string[] | null | undefined>; // string[]
原理

type NonNullable<T> =  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<T extends (...args: any) => 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<T extends (...args: any) => any> = 
T extends (...args: any) => infer R ? R : any
懂了 Parameters,也就懂了 ReturnType,

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

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

相关推荐

  1. TS高级类型

    2024-06-09 10:08:01       34 阅读
  2. TS高级类型

    2024-06-09 10:08:01       8 阅读
  3. 0008、ts类型推论

    2024-06-09 10:08:01       20 阅读
  4. ts中高阶类型理解

    2024-06-09 10:08:01       17 阅读
  5. 0010、TS字面量类型

    2024-06-09 10:08:01       17 阅读
  6. 3、TS类型断言

    2024-06-09 10:08:01       11 阅读
  7. TS设置接收形参类型

    2024-06-09 10:08:01       7 阅读
  8. TypeScript基础类型高级类型梳理总结

    2024-06-09 10:08:01       22 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-09 10:08:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-09 10:08:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-09 10:08:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-09 10:08:01       20 阅读

热门阅读

  1. kafka是什么?

    2024-06-09 10:08:01       10 阅读
  2. Docker概念速通

    2024-06-09 10:08:01       7 阅读
  3. RuoyiAdmin项目搭建及Docker 部署备忘

    2024-06-09 10:08:01       13 阅读
  4. 学习分享-注册中心Naocs的优雅上下线

    2024-06-09 10:08:01       9 阅读
  5. Redisson 源码分析 —— 调试环境搭建

    2024-06-09 10:08:01       9 阅读
  6. 面试题之webpack与vite系列

    2024-06-09 10:08:01       7 阅读