ts中高阶类型的理解

高阶类型是TypeScript中一种高级的类型操作,它允许你创建或修改现有类型的结构。这些类型通常作为其他类型的参数(即“泛型”)来定义新的类型。以下是一些常见的高阶类型示例:

  1. 映射类型(Mapped Types): 映射类型允许你基于一个现有类型创建一个新的类型,并对每个属性执行某种转换操作。例如,Partial<T> 类型会将 T 中的所有属性都变为可选:
       interface Person {name: string;age: number;}type PartialPerson = Partial<Person>;// 等同于 { name?: string; age?: number; }

  2. Pick<T, K> 和 Omit<T, K>
    • Pick<T, K> 从类型 T 中选择指定键 K 的属性构成新类型。
           interface Person {name: string;age: number;address: string;}type NameAndAge = Pick<Person, 'name' | 'age'>;// 等同于 { name: string; age: number; }

    • Omit<T, K> 则是从类型 T 中排除指定键 K 的属性。
           type WithoutAddress = Omit<Person, 'address'>;// 等同于 { name: string; age: number; }

  1. Record<K, V>: 创建一个对象类型,其中所有属性的键都是由 K 类型表示,值都是由 V 类型表示。
       type UserMap = Record<string, Person>; // 等同于 { [key: string]: Person; }

  2. ** keyof T 和 infer 关键字**:
     type KeysOfPerson = keyof Person; // "name" | "age" | "address"

    infer 在条件类型中用于推断类型。例如,在声明泛型时可以使用 infer 来从匹配的类型中提取子类型。

         type Unpacked<T> = T extends (infer U)[] ? U : T;// 此类型用于从数组类型中提取元素类型

 3.Conditional Types(条件类型): 允许根据某些条件表达式来确定类型

   type TypeName<T> = T extends string ? 'string' :T extends number ? 'number' :T extends boolean ? 'boolean' :'unknown';

通过这些高阶类型,开发者可以在TypeScript中实现更复杂、更灵活的类型定义和转换,进一步提升代码的类型安全性和可读性。

infer 是 TypeScript 中用于在条件类型(Conditional Types)中进行类型推断的关键字。它的主要作用是根据某种条件来提取或推断出未知类型的值。

下面是一个更具体的 infer 示例,解释如何从泛型参数中提取类型:

type MyPair<T> = [T, T];// 使用 infer 关键字定义一个 ExtractType 类型,它能从 MyPair 类型中提取出元素类型
type ExtractType<T> = T extends MyPair<infer U> ? U : never;// 测试用例
let pair1: MyPair<number> = [1, 2];
type NumberFromPair = ExtractType<typeof pair1>; // NumberFromPair 的类型被推断为 numberlet pair2: MyPair<string> = ['hello', 'world'];
type StringFromPair = ExtractType<typeof pair2>; // StringFromPair 的类型被推断为 string

在这个例子中:

  • 我们首先定义了一个泛型类型 MyPair,表示一个包含两个相同类型元素的数组。
  • 然后定义了 ExtractType 这个条件类型,使用 infer 来推断 MyPair 中的元素类型 U
  • 当 T 能够匹配 MyPair<infer U> 形式时,ExtractType<T> 的结果就是 U 类型;否则结果是 never 类型(表示不可能存在的类型)。

通过这种方式,我们可以从已知类型中“提取”或“推断”出内部嵌套的未知类型,这对于处理复杂的类型关系非常有用。

<infer U> ? U : never 这部分并不是固定的写法,但它是一种常见的 infer 关键字与条件类型结合的用法。

这里的结构遵循了 TypeScript 中条件类型的语法:

T extends U ? X : Y

其中:

  • T 是要检查的类型。
  • U 是用于比较的基础类型或类型构造器(在这个例子中是 MyPair<infer U>)。
  • X 是当 T 扩展自(或者说匹配)U 时的结果类型。
  • Y 是当 T 不扩展自(不匹配)U 时的结果类型。

在 <infer U> ? U : never 这个表达式中:

  • infer U 表示我们正在尝试从 T 中推断出一个未知类型 U
  • 当 T 可以成功地被解释为 MyPair<某种类型> 的形式时,infer U 将能够推断出那个“某种类型”,并将其作为结果类型返回,即 U
  • 如果 T 不能被解释为此形式,则结果类型是 never,表示不存在这样的类型。

所以这不是固定写法,但这种模式对于基于泛型或其他复杂类型进行类型推断的场景非常常见。根据具体需求,infer 和条件类型的具体使用可能会有所不同。

extends 在 TypeScript 中有多种含义和用法,主要体现在以下两个方面:

  1. 类继承: 在定义类(Class)时,可以使用 extends 关键字实现类之间的继承关系。子类会继承父类的属性和方法。
       class Animal {name: string;constructor(name: string) {this.name = name;}makeSound(): void {console.log('Making a sound');}}class Dog extends Animal {breed: string;constructor(name: string, breed: string) {super(name);this.breed = breed;}bark(): void {console.log('Woof woof!');}}

  2. 类型兼容性检查与条件类型: 在类型系统中,extends 用于判断一个类型是否兼容或扩展自另一个类型。这在泛型约束、接口继承以及条件类型中非常有用。

         

  • 泛型约束:限制泛型参数必须满足特定类型的要求。
         function identity<T extends string>(arg: T): T {return arg;}

    上述代码中的 `T extends string` 表示传入的泛型参数 `T` 必须是字符串类型或者其子类型。

  • 条件类型:根据条件判断返回不同的类型。
         type Unpacked<T> = T extends (infer U)[] ? U : T;

    此处的 `extends` 用于在条件类型表达式中进行类型检查,如果 `T` 扩展自数组类型,则推断并返回数组元素类型 `U`,否则返回 `T` 类型本身。

  • 总结来说,extends 是 TypeScript 中用来表示继承和类型兼容性的重要关键字,在面向对象编程和类型系统的复杂逻辑处理中起着关键作用。

Partial<T> 是 TypeScript 中的一个内置工具类型,它的作用就是将类型 T 中的所有属性都变为可选(optional)。

例如,假设我们有一个接口:

interface Person {name: string;age: number;address?: string; // 这个已经是可选属性了
}

如果我们想创建一个新的类型,其中所有的属性都是可选的,可以使用 Partial<T> 类型:

type OptionalPerson = Partial<Person>;// 等同于
// type OptionalPerson = {
//   name?: string;
//   age?: number;
//   address?: string;
// }

这样一来,当你在代码中使用 OptionalPerson 类型时,就不需要为任何属性提供值。而如果某个变量声明为 Person 类型,则必须为其所有非可选属性赋值。

Partial<T> 的核心功能就是将类型 T 中的所有属性(包括索引签名和方法)都变为可选。这意味着当你使用 Partial<T> 时,不需要为这些属性提供值就可以创建该类型的对象实例。

虽然从功能上看,Partial<T> 主要是为了实现属性转可选,但它的应用场景非常广泛,尤其是在处理可能不完整的数据结构、更新现有对象的部分属性或与外部接口交互(如API请求响应可能只返回部分数据)等方面,能有效提高代码的灵活性和健壮性。

keyof T 是 TypeScript 中用于获取类型 T 的所有公共属性键的类型操作符。它会返回一个联合类型,该联合类型包含 T 类型中所有可索引的公共属性名。

interface Person {name: string;age: number;address?: string; // 可选属性
}type PersonKeys = keyof Person; // 等同于 "name" | "age" | "address"

在这个例子中,PersonKeys 类型包含了 Person 接口的所有属性名称(包括可选属性)作为字符串字面量类型。

当你使用 keyof T 时,TypeScript 会生成一个表示对象所有可能键的类型,这对于编写更灵活且类型安全的代码非常有用,尤其是在处理映射、枚举对象属性或创建基于现有类型的接口和函数参数时。

当你在 TypeScript 中使用 keyof T 这个操作符时,TypeScript 编译器会分析类型 T 的结构,并生成一个新的类型,这个新类型包含了所有可以作为 T 类型对象的属性键(即键名)。

interface Person {name: string;age: number;address?: string; // 可选属性
}type KeysOfPerson = keyof Person;// 此时,KeysOfPerson 类型被推断为 "name" | "age" | "address"

在这个例子中,KeysOfPerson 类型代表了可以从 Person 接口中访问的所有合法属性名称。这意味着任何变量如果声明为 KeysOfPerson 类型,它可以是 "name""age" 或 "address"

这种类型的用途很多,比如在编写映射函数、创建动态属性访问或约束函数参数必须是给定类型的有效属性名等场景。

keyof T 主要用来获取类型 T 的所有合法键名,并生成一个可以表示这些键名联合类型的类型。这个类型主要用于检查和限制变量必须是给定对象类型的所有可能键名之一,确保在代码中使用的属性名是有效的、与类型 T 匹配的。它有助于提高代码的健壮性和可维护性,尤其是在处理动态属性访问或映射操作等场景时。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/744464.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

豆瓣书影音存入Notion

使用Python将图书和影视数据存放入Notion中。 &#x1f5bc;️介绍 环境 Python 3.10 &#xff08;建议 3.11 及以上&#xff09;Pycharm / Vs Code / Vs Code Studio 项目结构 │ .env │ main.py - 主函数、执行程序 │ new_book.txt - 上一次更新书籍 │ new_video.…

GitLab 中国发行版 15.11 重点功能解读【一】

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 更多关于极狐GitLab 或者 DevOps 的最佳实践&#xff0c;可以关…

全球首个 AI 软件工程师 Devin它来了!

如果您想每日获取AI最新新闻,欢迎关注文章底部的公众号 Cognition AI 发布 AI 软件工程师 Devin 初创公司 Cognition 近日发布公告,宣布推出全球首个 AI 软件工程师 Devin,并号称会彻底改变人类构建软件的方式。Devin 擅长长期推理能力,可以自主规划和完成软件项目,并在此…

ElasticSearch深度分页问题如何解决

文章目录 概述解决方法深度分页方式from size深度分页之scrollsearch_after 三种分页方式比较 概述 Elasticsearch 的深度分页问题是指在大数据集上进行大量分页查询时可能导致的性能下降和资源消耗增加的情况。这种情况通常发生在需要访问大量数据的情形下&#xff0c;比如用…

【OpenBayes 官方教程】数据读写绑定功能

本教程主要为大家介绍怎样在 OpenBayes 上进行数据的绑定以及如何使用已绑定的数据&#xff0c;新朋友点击下方链接注册后&#xff0c;即可获得 4 小时 RTX 4090 5 小时 CPU 的免费使用时长哦&#xff01; 注册链接 注册 - OpenBayes 首先&#xff0c;创建一个新的容器。 然…

非光滑非凸规划

目录 一&#xff0c;非凸函数的近端梯度下降 1&#xff0c;凸函数的近端梯度下降 2&#xff0c;非凸函数的近端梯度下降 一&#xff0c;非凸函数的近端梯度下降 1&#xff0c;凸函数的近端梯度下降 参考近端梯度下降 2&#xff0c;非凸函数的近端梯度下降

11.17定时调度(血干JAVA系类)

定时调度 11.17.1 Timer 类11.17.2 TimerTask 类11.17.3范例——定时操作【例11.52】建立TimerTask的子类【例11.53】建立测试类&#xff0c;进行任务调度 11.17.1 Timer 类 11.17.2 TimerTask 类 要想执行具体的任务&#xff0c;则必须使用Tim erTas k类。Tim erTas k类是一个…

工业界真实的推荐系统(小红书)-离散特征处理、矩阵补充模型、双塔模型

课程特点&#xff1a;系统、清晰、实用&#xff0c;原理和落地经验兼具 b站&#xff1a;https://www.bilibili.com/video/BV1HZ421U77y/?spm_id_from333.337.search-card.all.click&vd_sourceb60d8ab7e659b10ea6ea743ede0c5b48 讲义&#xff1a;https://github.com/wangsh…

vid2vid(Video-to-Video Synthesis)论文详读和理解

论文&#xff1a;https://arxiv.org/abs/1808.06601 代码&#xff1a;https://github.com/NVIDIA/vid2vid

北斗卫星推动数智油田建设

北斗卫星推动数智油田建设 中国石油大港油田采油三厂深入推动北斗智能终端在智能巡检、安全监督、油井导航、坐标测绘等多场景应用&#xff0c;实现了人工查井向智能巡检的变革。截至2月下旬&#xff0c;场景覆盖率达100%&#xff0c;高效助推大港南部“双高”老区数智油田建设…

第一个C语言hello world

#include <stdio.h> int main() {printf("hello world ! \n");//打印函数return 0; } "#" : 预处理标志 include <> : 表示预处理的文件在<>内 stdio.h : 标准的io头文件 // io &#xff1a; 输入输出 // printf()…

史上最牛Linux详解,看完直接带你由入门到精通!

第一部分&#xff1a;入门 第二部分&#xff1a;成为一名linux高级用户&#xff1a; 第三部分&#xff1a;成为一名Linux系统管理员 第四部分&#xff1a;成为一名Linux服务器管理员 因文章内容过长&#xff0c;目录先放这些&#xff0c;因为接下来还要放一些内容 小编13年上海…

5款可以免费使用的 UI 设计软件

在我们分享五个有用的原型工具之前&#xff0c;完成原型并优化界面。这是 UI 设计师的任务。UI 设计软件对设计师来说非常重要。UI 设计工具的使用是否直接影响最终结果&#xff0c;然后有人会问&#xff1a;UI 界面设计用什么软件&#xff1f;一些 UI 设计师和对 UI 设计感兴趣…

二,几何相交---4,BO算法---(4)可能的三种情况

从上到下&#xff0c;扫描线经过有三种情况&#xff1a; 第一种情况&#xff0c;加入线段e的左端点&#xff0c;那么原来的状态pred->suc变成pred->e->suc 第二种情况&#xff0c;经过线段e的右端点&#xff0c;状态pred->e->suc&#xff0c;变成pred->suc&a…

Oracle 死锁、指标汇总

一、Oracle RAC 架构 待~ "SYS"."V_$SESSION" 与 "SYS"."GV_$SESSION"的区别 哪个列可以区分V$和GV$: 添加条件 S.INST_ID USERENV(INSTANCE) SELECT * FROM GV$SESSION S WHERE S.USERNAME SCOTT AND S.INST_ID USERENV(IN…

SimplifyRODataLoads - 优化阅读笔记

// 只支持 X86 static cl::opt<bool> SimplifyRODataLoads("simplify-rodata-loads",cl::desc("通过用相应节中找到的常数替换内存操作数&#xff0c;简化来自只读节的加载"),cl::cat(BoltOptCategory));测试用例&#xff1a; ./build4/bin/llvm-li…

如何在Linux部署Docker Registry本地镜像仓库并实现无公网IP远程连接

文章目录 1. 部署Docker Registry2. 本地测试推送镜像3. Linux 安装cpolar4. 配置Docker Registry公网访问地址5. 公网远程推送Docker Registry6. 固定Docker Registry公网地址 Docker Registry 本地镜像仓库,简单几步结合cpolar内网穿透工具实现远程pull or push (拉取和推送)…

Linux/Ubuntu/Debian基本命令:文本操作

Linux系统真的超级好用&#xff0c;免费&#xff0c;有很多开源且功能强大的软件。尤其是Ubuntu&#xff0c;真的可以拯救十年前的老电脑。 下面是用于在命令行界面&#xff08;Terminal&#xff09;中进行文本操作的键盘快捷键&#xff0c; 这些快捷方式对于高效的文本编辑非常…

为什么拥有C语言基础的人,依然学不会C++?

为什么拥有C语言基础的人&#xff0c;依然学不会C? 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「C语言 的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&am…

Vue+OpenLayers7入门到实战:OpenLayers加载必应地图(BingMap)

返回《Vue+OpenLayers7》专栏目录:Vue+OpenLayers7入门到实战 前言 本章介绍如何使用OpenLayers7在地图上如何加载必应地图(BingMap)。 需要提前到必应开发者中心申请对应的地图访问api key才可以加载地图。 二、依赖和使用 "ol": "7.5.2"使用npm安装…