一介*书生
愿你熬过苦难,依旧努力生活。

1.TS内置高级类型Partial&Pick&Required&Readonly 

1.1、Partial 

Partial 可以快速把某个接口类型中定义的所有属性变成可选的

interface ApiKey {
  id: number;
  name: string;
}

const dataType1: ApiKey = {
  id: 1,
  name: 'static'
}
const dataType2: ApiKey = {
  name: 'json'
}
这段代码会在编译报错:

 

 因为dataType2的类型是ApiKey,ApiKey中idname都是必选的,这导致编译报错。假如ApiKey中的参数是可选的,那么这个问题就会不复存在,而Partial的作用就在于此,它可以帮助我们把ApiKey中的所有属性都变成可选的

我们用Partial来重写一下这个栗子:

const dataType2:  Partial<ApiKey> = {
  name: 'json'
}
这样就不会报错啦!

1-2、Pick 

可以选择一个原来的接口中一部分的属性定义
interface People {
  name: string
  age: number
}
type somePeople = Pick<People,'name'>
let onlyName:somePeople = { 
  name:"112"
}
选择了接口中的name属性,那么该属性就必须含有

1-3、Required

Partial刚好相反,将一个定义中的属性全部变成必选参数
// 必选参数
interface People1 {
  name?: string;
  age?: number;
}
// 类型 "{ name: string; }" 中缺少属性 "age",但类型 "Required<People>" 中需要该属性
const person2: Required<People1> = {
  name:"11"
}

1-4、Readonly 

只读,让一个定义中的所有属性都变成只读参数
interface People3 {
  name: string
  age: number,
  dog:{
      name:string
      age:number
  }
}
const xiaoling: Readonly<People3> = {
  name: '小凌', // 只读
  age: 18, // 只读
  dog:{
      age:1,
      name:'大黄'
  }
}
// 但是是浅层的
xiaoling.name = '大凌' // 无法分配到 "name" ,因为它是只读属性。
xiaoling.dog.age = 2 // 可以

2.联合类型(UnionType)

首先是联合类型的介绍,也是一切的起源

let a: string | number | boolean = '123' // 变量a的类型既可以是string,
a = 123 // 也可以是number
a = true // 也可以是boolean

3.keyof

将一个类型的属性名全部提取出来当做联合类型
// key of 使用
interface People5 {
  name: string;
  age: number;
}
// keyof 取 interface 的键
// type keys = "name" | "age"
type keys = keyof People5;
// 假设有一个 object 如下所示,
// 我们需要使用 typescript 实现一个 get 函数来获取它的属性值
const xiaozhang:People5 = {
  name: '小张',
  age: 12
}
function get<T extends object, K extends keyof T>(o: T, name: K): T[K] {
  return o[name]
}
console.log(get(xiaozhang,'age')) // 12
console.log(get(xiaozhang,'name')) // 小张
// error 类型“"address"”的参数不能赋给类型“keyof People”的参数。
console.log(get(xiaozhang,'address'))

keyof 与 Object.keys 略有相似,只不过 keyof 取 interface 的键

4.映射(Record)

Record用于属性映射

搭配联合类型
type RequestMethods = 'GET'|'POST'| 'DELETE'
type MethodsAny = Record<RequestMethods, any>
let mothod1:MethodsAny = {
    GET:"1",
    POST:'1',
    DELETE:'1'
}
let mothod2:MethodsAny = {
    GET:"1",
    POST:'1',
    DELETE:'1', // 缺少,会报错,因为它为必须存在的
    PUT:'111' // error “PUT”不在类型“MethodsAny”中
}
搭配接口使用
interface PersonModel {
  name:string,
  age:number
}
// [x: string]: PersonModel;
type student = Record<string, PersonModel>
let students:student = {
  student1:{
      name:'小凌',
      age:18
  },
  student2:{
      name:'小李',
      age:19
  }
}

5.Exclude(排除)

ts中可以排除 联合类型 中一部分的内容
注意:Exclude用来操作联合类型

type havTypes = 'name' | 'age' | 'sex'
type someTypes = Exclude<havTypes,'sex'>
const myTypes1:someTypes = 'name' // 可以
const myTypes2:someTypes = 'sex' // 错误 不能将类型“"sex"”分配给类型“someTypes”

6.Omit (省略)

ts中就是将接口或者类型的键值对删除一部分
// 省略
interface People {
  name: string;
  age: number;
}
type somePeople = Omit<People,'name'>
/**
type somePeople = {
  age: number;
}
*/

7.ReadonlyArray(只读数组)

创建一个数组,数组中的索引不允许被修改

我们知道当我们使用const创建对象或者数组时,其实是可以修改其内部属性的,但是有的时候我们可能不需要其内部能够被修改,这时候我们就需要用ReadonlyArray

实现的方式有两种:

// 方法1:通过类型断言的方式
const arr = ['小伟','小铁','小涵','小凌'] as const
arr[3] = '帅哥'; //  报错 无法分配到 "3" ,因为它是只读属性

// 方法2:使用ReadonlyArray
const arr2 : ReadonlyArray<string> = ['木兰','盾山','凯','百里守约']
arr2[3] = '百里玄策' // 报错 类型“readonly string[]”中的索引签名仅允许读取
你是不是就想知道as constReadonlyArray这两者的区别在哪里?
区别在于as const是深层次的,尽管数组内放的对象,对象内部数据也是不能被修改的。ReadonlyArray则是‘浅层’
const:

 ReadonlyArray:

 可以看到修改ReadonlyArray数组内的第二层其实是可以的

 

posted on 2023-02-21 18:11  一介-_-书生  阅读(145)  评论(0编辑  收藏  举报