Typescript高级类型Record,Partial,Readonly详解

目录
  • 联合类型
  • keyof
  • Record
  • Partial (部分的; 不完全的)
  • Required(必须的)
  • Pick(选择)
  • Readonly (意思是只读的)
  • Exclude(排除)
  • Omit (省略的)
  • ReadonlyArray(只读数组)

TypeScript 是一种类型化的语言,允许你指定变量、函数参数、返回的值和对象属性的类型。

下面介绍Typescript高级类型Record,Partial,Readonly等知识。

联合类型

/* 首先是联合类型的介绍 */
let a: string | number = '123' // 变量a的类型既可以是string,也可以是number
a = 123

keyof

将一个类型的属性名全部提取出来当做联合类型

// 1. 定义一个接口
interface Person {
  name: string
  age: number
}

type PersonKeys = keyof Person // 等同于 type PersonKeys = 'name' | 'age'

const p1: PersonKeys = 'name' // 可以
const p2: PersonKeys = 'age' // 可以
const p3: PersonKeys = 'height' // 不能将类型“"height"”分配给“name | age”

Record

Record用于属性映射,听不懂?直接上案例

定义一个普通的对象类型

搭配联合类型用法

同样可以映射对象,让对象的每个属性都是一个拥有特定键值对的类型

Record的实现原理
Record的内部定义,接收两个泛型参数

type Record<K extends string | number | symbol, T> = {
    [P in K]: T;
}

逐步解析

  • 泛型K即为第一次参数
  • p in xx 又是什么意思呢?
    in的意思就是遍历,如上就是将 类型string进行遍历,也就是string
  • 每个属性都是传入的T类型,如 string: PersonModel

Partial (部分的; 不完全的)

ts中就是让一个定义中的所有属性都变成可选参数

// 定义一个Person接口
interface Person {
  name: string
  age: number
}

// 但是我们有可能数据是请求过来的,刚开始我们需要定义一个空对象,如下。
const person1: Person = {}
/**
  但是这样就加粗样式会出现报错,类型“{}”缺少类型“Person”中的以下属性: name, age。
  可能我们可以更改定义方式如下,但是有的时候我们不想破坏事先的定义,或者不能破坏
  interface Person {
    name?: string
    age?: number
  }
*/

/**
  那这个时候我们就可以用到typescript自带的高级类型 Partial,就相当于将上方接口所有属性变成可选的
  将我们需要定义的类型当做泛型传入Partial中,那么就相当于当前的类型里面的所有属性都是可选的
 */
const person2: Partial<Person> = {} // 可以
const person3: Partial<Person> = { name: 'xiaodu' } // 可以
const person4: Partial<Person> = { height: 1.88 } // 报错 “height”不在类型“Partial<Person>”中

Partial的实现原理
Partial的内部定义

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

逐步解析

  • 将一个类型的属性名全部提取出来当做联合类型
  • 将 age和name进行遍历
  • [P in keyof T]? 的冒号就代表 可选 的参数
  • T[P] 就代表 如 Person[name]代表的是 string 类型

Required(必须的)

和Partial刚好相反,将一个定义中的属性全部变成必选参数

Required的实现原理
Required的内部定义

type Required<T> = {
    [P in keyof T]-?: T[P];
}

逐步解析

  • 将一个类型的属性名全部提取出来当做联合类型
  • 将 age和name进行遍历
  • 在?之前加个-,代表着这个属性是必须的。
  • T[P] 就代表 如 Person[name]代表的是 string 类型

Pick(选择)

ts中可以选择一个原来的接口中一部分的属性定义

如果想要选择多个属性定义呢?

pick的实现原理

type Pick<T, K extends keyof T> = {
  [P in K]: T[P]
}

pick接收两个泛型

  • 第一个泛型 T 便是 interface 或者 type 定义
  • 第二个就是第一个定义中的属性, extends就代表继承

K extends keyof T 等同于 k extends ‘name’ | ‘age’,意思就是k只能是age或者name Readonly (意思是只读的)

Readonly (意思是只读的)

ts中就是让一个定义中的所有属性都变成只读参数

type Pick<T, K extends keyof T> = {
  [P in K]: T[P]
}

可以看到Readonly可以将接口所有属性变为只读的不可修改的,但是是浅层的。
Readonly的实现原理
Readonly的内部定义

type Readonly<T> = {
  readonly [P in keyof T]: T[P];
}

逐步解析

  • 将一个类型的属性名全部提取出来当做联合类型
  • 将 age和name进行遍历
  • readonly 修饰符代表属性是只读的
  • T[P] 就代表 如 Person[name]代表的是 string 类型

Exclude(排除)

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

Exclude的原理

type Exclude<T, U> = T extends U ? never : T

传入两个泛型

  • 我们这里用 MyTypes 也就是 ‘name’ | ‘age’ | ‘height’ 去代表 T
  • 用 name 属性去代表第二个泛型 U
  • T extends U 就判断是否’name’ | ‘age’ | ‘height’ 有 name, 有name就返回never,就代表将其排除

Omit (省略的)

ts中就是将接口或者类型的键值对删除一部分

Omit原理
也就是上面所讲解的知识点拼凑起来的

type Omit<T, K extends string | number | symbol> = {
  [P in Exclude<keyof T, K>]: T[P]
}

ReadonlyArray(只读数组)

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

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

const arr: number[] = [1, 2, 3, 4, 5]
arr[0] = 3 

方法1:通过类型断言的方式

方法2:使用ReadonlyArray,需要传入一个泛型来约束数组中的索引类型

这个时候你是不是就想知道as constReadonlyArray这两者的区别在哪里?

区别在于as const是深层次的,尽管数组内放的对象,对象内部数据也是不能被修改的。ReadonlyArray则是‘浅层’的。

as const

ReadonlyArray

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

到此这篇关于Typescript高级类型Record,Partial,Readonly等介绍的文章就介绍到这了,更多相关Typescript高级类型Record内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 你不知道的 TypeScript 高级类型(小结)

    前言 对于有 JavaScript 基础的同学来说,入门 TypeScript 其实很容易,只需要简单掌握其基础的类型系统就可以逐步将 JS 应用过渡到 TS 应用. // js const double = (num) => 2 * num // ts const double = (num: number): number => 2 * num 然而,当应用越来越复杂,我们很容易把一些变量设置为 any 类型,TypeScript 写着写着也就成了 AnyScript.为了让大家能更加深入

  • 你需要知道的TypeScript高级类型总结

    目录 1. 字面量类型 (1)字符串字面量类型 (2)数字字面量类型 (3)布尔字面量类型 (4)模板字面量类型 2. 联合类型 (1)基本使用 (2)限制 (3)可辨识联合类型 3. 交叉类型 (1)基本实用 (2)使用场景 4. 索引类型 (1)索引类型查询操作符 (2)索引访问操作符 (3)应用 5. 条件类型 (1)基本概念 (2)创建自定义条件类型 (3)条件类型的类型推断 6. 类型推断 (1)基础类型 (2)多类型联合 (3)上下文类型 7. 类型保护 (1)instanceof

  • typescript中高级类型Record详解

    ts文档上对Record的介绍不多,但却经常用到,Record是一个很好用的工具类型.他会将一个类型的所有属性值都映射到另一个类型上并创造一个新的类型,先看下Record的源码. /** * Construct a type with a set of properties K of type T */ type Record<K extends keyof any, T> = { [P in K]: T; }; 好像源码也比较简单,即将K中的每个属性([P in K]),都转为T类型.常用的

  • TypeScript 内置高级类型编程示例

    目录 TypeScript 类型编程 TypeScript 内置高级类型 Pick<Type, Keys> Exclude<UnionType, ExcludedMembers> ReturnType<Type> 更多类型体操学习 TypeScript 类型编程 TypeScript 的类型系统,最基本的是简单对应 JavaScript 的 基本类型,比如 string.number.boolean 等,然后是新增的 tuple.enum.复合类型.交叉类型.索引类型等

  • Typescript高级类型Record,Partial,Readonly详解

    目录 联合类型 keyof Record Partial (部分的; 不完全的) Required(必须的) Pick(选择) Readonly (意思是只读的) Exclude(排除) Omit (省略的) ReadonlyArray(只读数组) TypeScript 是一种类型化的语言,允许你指定变量.函数参数.返回的值和对象属性的类型. 下面介绍Typescript高级类型Record,Partial,Readonly等知识. 联合类型 /* 首先是联合类型的介绍 */ let a: st

  • Python 高级专用类方法的实例详解

    Python 高级专用类方法的实例详解 除了 __getitem__ 和 __setitem__ 之外 Python 还有更多的专用函数.某些可以让你模拟出你甚至可能不知道的功能.下面的例子将展示 UserDict 一些其他专用方法. def __repr__(self): return repr(self.data) (1) def __cmp__(self, dict): (2) if isinstance(dict, UserDict): return cmp(self.data, dic

  • Java的类型擦除式泛型详解

    Java选择的泛型类型叫做类型擦除式泛型.什么是类型擦除式泛型呢?就是Java语言中的泛型只存在于程序源码之中,在编译后的字节码文件里,则全部泛型都会被替换为原来的原始类型(Raw Type),并且会在相应的地方插入强制转型的代码. 因此,对于运行期间的Java程序来说ArrayList< Integer>和ArrayList< String>其实是同一个类型.这也就是Java选择的泛型类型叫做类型擦除式泛型的原因. ArrayList<String> stringAr

  • TypeScript数组的定义与使用详解

    目录 基本定义 声明数组时直接初始化 访问数组 Array对象 声明数组时指定数组大小 两种定义方式 声明多维数组(含泛型) 普通版 泛型版 类数组 数组解构 通过接口描述数组 数组迭代 基本定义 声明数组时直接初始化 // 基本定义 let arr:number[] = [1,2,3]; let arrS: string[] = ["1","2"] 如果数组声明时未设置类型,则会被认为是 any 类型,在初始化时根据第一个元素的类型来推断数组的类型. 访问数组 A

  • Python对象类型及其运算方法(详解)

    基本要点: 程序中储存的所有数据都是对象(可变对象:值可以修改 不可变对象:值不可修改) 每个对象都有一个身份.一个类型.一个值 例: >>> a1 = 'abc' >>> type(a1) str 创建一个字符串对象,其身份是指向它在内存中所处的指针(在内存中的位置) a1就是引用这个具体位置的名称 使用type()函数查看其类型 其值就是'abc' 自定义类型使用class 对象的类型用于描述对象的内部表示及其支持的方法和操作 创建特定类型的对象,也将该对象称为该类

  • C/C++ ip地址与int类型的转换实例详解

    C/C++ ip地址与int类型的转换实例详解 前言 最近看道一个面试题目,大体意思就是将ip地址,例如"192.168.1.116"转换成int类型,同时还能在转换回去 思路 ip地址转int类型,例如ip为"192.168.1.116",相当于"."将ip地址分为了4部分,各部分对应的权值为256^3, 256^2, 256, 1,相成即可 int类型转ip地址,思路类似,除以权值即可,但是有部分字符串的操作 实现代码 #include &l

  • Java的静态类型检查示例代码详解

    关于静态类型检查和动态类型检查的解释: 静态类型检查:基于程序的源代码来验证类型安全的过程: 动态类型检查:在程序运行期间验证类型安全的过程: Java使用静态类型检查在编译期间分析程序,确保没有类型错误.基本的思想是不要让类型错误在运行期间发生. 在各色各样的编程语言中,总共存在着两个类型检查机制:静态类型检查和动态类型检查. 静态类型检查是指通过对应用程序的源码进行分析,在编译期间就保证程序的类型安全. 动态类型检查是在程序的运行过程中,验证程序的类型安全.在Java中,编译期间使用静态类型

随机推荐