当前位置: 首页 > news >正文

Typescript高级: 深入理解infer关键字

概述

  • 在 TS 中,infer 是一个高级类型操作,特别是条件类型和映射类型中非常有用的关键字
  • 它在泛型中使用也会是一个强大工具,增强了类型推断的能力,让开发者更灵活地处理和操作类型
  • 它允许在泛型类型推导过程中捕获一个具体的类型,这对于编写复杂的类型转换和映射操作特别有用
  • infer 的定义
    • infer 表示在 extends 条件语句中以占位符出现的用来修饰数据类型的关键字
    • 被修饰的数据类型等到使用时才能被推断出来
  • infer 占位符式的关键字出现的位置
    • infer 出现在 extends 条件语句后的函数类型的参数类型位置上
    • infer 出现在 extends 条件语句后的函数类型的返回值类型上
    • infer 出现在类型的泛型具体化类型上

实现

1 )infer 出现在 extends 条件语句后的函数类型的参数类型位置上

// 定义了一个接口Customer,它描述了一个具有name(字符串类型)和moneyPaid(数字类型)属性的对象
interface Customer {name: stringmoneyPaid: number
}// 定义了一个函数类型,接受一个Customer类型的参数并返回一个字符串
type custFuncType = (cust: Customer) => string// 定义了一个泛型类型inferType<T>,这是理解的重点。这是一个条件类型,它使用了infer关键字
type inferType<T> = T extends (params: infer P) => any ? P : T// 定义了inferResultType类型别名,它是通过将前面定义的custFuncType类型作为参数传递给inferType得到的
type inferResultType = inferType<custFuncType>
  • 分析一下这行代码:type inferType<T> = T extends (params: infer P) => any ? P : T
    • T extends (params: infer P) => any
      • 这部分是一个类型测试,检查T是否可以赋值给一个函数类型
      • 该函数接受一个参数(我们称之为params)
      • infer P关键字在这里用于声明一个新的类型变量P,用来捕获T中函数参数的实际类型
    • ? P
      • 如果上面的测试为真(即T确实是一个函数类型)
      • 那么整个条件类型的结果就是捕获的参数类型P
    • : T
      • 如果上面的测试为假(即T不是函数类型或不匹配)
      • 则条件类型的结果就是T本身,不做任何改变
  • 最后一行代码 type inferResultType = inferType<custFuncType>
    • custFuncType是一个接受Customer类型参数的函数,所以infer P会捕获到这个参数类型
    • 因此,inferResultType 实际上就是Customer类型

2 ) infer 出现在 extends 条件语句后的函数类型的返回值类型上

// 定义了一个接口Customer,它描述了一个具有name(字符串类型)和moneyPaid(数字类型)属性的对象
interface Customer {custname: stringmoneyPaid: number
}
// 这个类型定义了一个函数,该函数接受一个Customer类型的参数并返回一个字符串
type custFuncType = (cust: Customer) => string
type inferType<T> = T extends (params: any) => infer P ? P : T
type inferResultType = inferType<custFuncType>
  • 核心在这里, type inferType<T> = T extends (params: any) => infer P ? P : T
    • 上面,inferType 的 infer 在返回值的位置上
    • infer P 表示“推断出一个类型 P”,这个 P 是函数的返回类型
    • 它根据 extends 的检查结果来选择不同的类型
    • 如果 T 是一个符合 (params: any) => … 形式的函数类型
    • 那么表达式的结果是 P(即函数的返回类型)
    • 否则,表达式的结果是 T 本身
  • 最后,type inferResultType = inferType<custFuncType>
    • 由于,custFuncType 是一个返回值为 string 的函数类型
    • 符合,inferType 内部的三元推导的条件,因为 返回值是 P, 而在这里P又是 string 类型
    • 所以,type inferResultType 就是 string 类型

3 ) infer 出现在类型的泛型具体化类型上

class Subject {constructor(public id: number, public name: string) {}
}const chineseSubject = new Subject(100, "语文");
const mathSubject = new Subject(101, "数学");type ElementOfSet<T> = T extends Set<infer E> ? E : never;const subjectsSet = new Set<Subject>([chineseSubject, mathSubject]);type SubjectType = ElementOfSet<typeof subjectsSet>;// 使用推断出的SubjectType类型
function printSubject(subject: SubjectType) {console.log(`学科ID: ${subject.id}, 学科名称: ${subject.name}`);
}printSubject(chineseSubject);
  • 核心代码在这里:type ElementOfSet<T> = T extends Set<infer E> ? E : never;
    • 如果 参数 T 属于 Set 类型,则 ElementOfSet 则是 E 的类型
    • 这里 Set<infer E> 使用 infer E 推导出 E的类型,如果符合 extends 条件,则返回E,否则返回 never
  • const subjectsSet = new Set<Subject>([chineseSubject, mathSubject]);
    • 这里 subjectsSet 是一个 Set 类型,而且单个元素是 Subject 类型
  • type SubjectType = ElementOfSet<typeof subjectsSet>;
    • ElementOfSet<typeof subjectsSet> 这里符合内部条件,所以,它最终是一个 Subject 类型
  • 所以,在最后,printSubject 中完美运行

总结

  • infer关键字在TypeScript中为泛型编程提供了一个强大的工具
  • 它不仅增强了类型系统的表达能力,还使开发者能够编写出更加灵活和精确的类型定义
  • 通过掌握infer的使用,你能够在处理复杂类型逻辑和类型转换时更加游刃有余
  • 提升代码的类型安全性和可维护性

相关文章:

Typescript高级: 深入理解infer关键字

概述 在 TS 中&#xff0c;infer 是一个高级类型操作&#xff0c;特别是条件类型和映射类型中非常有用的关键字它在泛型中使用也会是一个强大工具&#xff0c;增强了类型推断的能力&#xff0c;让开发者更灵活地处理和操作类型它允许在泛型类型推导过程中捕获一个具体的类型&a…...

JQC-3FF-S-Z 继电器模块使用(arduino)

前言 继电器模块可以控制电流的接通和非接通状态&#xff0c;和开关一样。实际上是用小电流去控制大电流运作的一种“自动开关” 本文只是简单使用继电器模块做一个 led 点亮和熄灭的案例&#xff0c;结合案例可以和 nodemcu 等板子结合做出远程控制开关。 材料准备 杜邦线…...

黑马一站制造数仓实战2

问题 DG连接问题 原理&#xff1a;JDBC&#xff1a;用Java代码连接数据库 Hive/SparkSQL&#xff1a;端口有区别 可以为同一个端口&#xff0c;只要不在同一台机器 项目&#xff1a;一台机器 HiveServer&#xff1a;10000 hiveserver.port 10000 SparkSQL&#xff1a;10001…...

网络I/O模型

网络I/O模型 同步I/O阻塞I/O非阻塞I/OI/O多路复用select函数接口示例 poll函数接口示例 poll 和 select 的区别epoll原理&#xff1a;示例 异步I/O 同步I/O 阻塞I/O 一个基本的C/S模型如下图所图&#xff1a;其中 listen()、connect()、write()、read() 都是阻塞I/O&#xff0…...

Docker 简介和安装

目录 Docker 是什么 跟普通虚拟机的对比 打包、分发、部署 Docker 部署的优势 Docker 通常用来做什么 重要概念&#xff1a;镜像、容器 安装 镜像加速源 Docker 是什么 Docker 是一个应用打包、分发、部署的工具 你也可以把它理解为一个轻量的虚拟机&#xff0c;它只虚…...

【源码】Spring Data JPA原理解析之Repository自定义方法命名规则执行原理(二)

Spring Data JPA系列 1、SpringBoot集成JPA及基本使用 2、Spring Data JPA Criteria查询、部分字段查询 3、Spring Data JPA数据批量插入、批量更新真的用对了吗 4、Spring Data JPA的一对一、LazyInitializationException异常、一对多、多对多操作 5、Spring Data JPA自定…...

Vue前端中从后端获取图片验证码

前端发送请求 <template><el-form :model"user" :rules"rules" ref"userForm" class"login" label-width"auto" style"max-width: 600px"><el-form-item label"用户名" prop"name…...

【源码】多语言H5聊天室/thinkphp多国语言即时通讯/H5聊天室源码/在线聊天/全开源

多语言聊天室系统&#xff0c;可当即时通讯用&#xff0c;系统默认无需注册即可进入群聊天&#xff0c;全开源 【海外聊天室】多语言H5聊天室/thinkphp多国语言即时通讯/H5聊天室源码/在线聊天/全开源 - 吾爱资源网...

gitlab 创建 ssh 和 token

文章目录 一、创建ssh key二、将密钥内容复制到gitlab三、创建token 一、创建ssh key 打开控制台cmd&#xff0c;执行命令 ssh-keygen -t rsa -C xxxxx xxxxx是你自己的邮箱 C:\Users\xx\.ssh 目录下会创建一个名为id_rsa.pub的文件&#xff0c;用记事本打开&#xff0c;并…...

Docker - Kafka

博文目录 文章目录 说明命令 说明 Docker Hub - bitnami/kafka Docker Hub - apache/kafka Kafka QuickStart Kafka 目前没有 Docker 官方镜像, 目前拉取次数最多的是 bitnami/kafka, Apache 提供的是 apache/kafka (更新最及时), 本文使用 bitnami/kafka bitnami/kafka 镜像…...

一键实现文件夹批量高效重命名:轻松运用随机一个字母命名,让文件管理焕然一新!

在数字化时代&#xff0c;文件夹管理是我们日常生活和工作中不可或缺的一部分。然而&#xff0c;随着文件数量的不断增加&#xff0c;文件夹命名的繁琐和重复成为了一个让人头疼的问题。你是否曾因为手动一个个重命名文件夹而感到枯燥乏味&#xff1f;你是否曾渴望有一种方法能…...

Vue3项目练习详细步骤(第二部分:主页面搭建)

主页面搭建 页面主体结构 路由 子路由 主页面搭建 页面主体结构 在vuews目录下新建Layout.vue文件 主页面内容主体代码 <script setup> import {Management,Promotion,UserFilled,User,Crop,EditPen,SwitchButton,CaretBottom } from element-plus/icons-vue imp…...

[个人总结]-java常用方法

1.获取项目根路径 user.dir是一个系统属性&#xff0c;表示用户当前的工作目录&#xff0c;大多数情况下&#xff0c;用户的当前工作目录就是java项目的根目录&#xff08;src文件的同级路径&#xff09; System.getProperty("user.dir") 结果&#xff1a;D:\code…...

什么是Java泛型?它有什么作用

Java泛型&#xff08;Generics&#xff09;是一种允许在定义类、接口和方法时使用类型参数的机制。泛型提供了一种机制&#xff0c;使得代码可以对多种类型的对象进行操作&#xff0c;而无需进行类型转换。 Java泛型的作用 类型安全&#xff1a;通过在编译时进行类型检查&…...

[机缘参悟-197] - 《道家-水木然人间清醒1》读书笔记 -21-看问题从现象到本质的层次

目录 1. 现象层&#xff1a; 2. 关联层&#xff1a; 3. 原因层&#xff1a; 4. 本质层&#xff1a; 5. 解决方案层&#xff1a; 6. 设计实现层&#xff1a; 7. 泛化&#xff1a; 8. 创新与发现&#xff1a; 看问题从现象到本质的层次是一个逐步深入、由表及里的过程。这…...

AIGC商业案例实操课,发觉其创造和商业的无限可能,Ai技术在行业应用新的商机

课程下载&#xff1a;https://download.csdn.net/download/m0_66047725/89307523 更多资源下载&#xff1a;关注我。 课程内容 1 AI为什么火 。写在课程前面的寄语 。AIGC标志性事件:太空歌剧院 。AI人工智能为什么这么火 &#xff0c;AI人工智能发展历程 。聊天AI会取…...

Java学习路径图

1.学习路径 JAVA架构师学习路径 2.路径拆解 2.1 Spring 2.1.1 SpringBoot原理 SpringBoot2学习视频 SpringBoot2笔记 SpringBoo2代码 2.2.2 SpringBoot项目 《谷粒商城》学习视频...

文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《考虑动态定价的新能源汽车能源站优化运行》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…...

【简单讲解下Fine-tuning BERT,什么是Fine-tuning BERT?】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…...

Docker搭建Redis主从 + Redis哨兵模式(一主一从俩哨兵)

我这里是搭建一主一从&#xff0c;俩哨兵&#xff0c;准备两台服务器&#xff0c;分别安装docker 我这里有两台centos服务器 主服务器IP&#xff1a;192.168.252.134 从服务器IP&#xff1a;192.168.252.135 1.两台服务器分别拉取redis镜像 docker pull redis 2.查看镜像 d…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

Web中间件--tomcat学习

Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机&#xff0c;它可以执行Java字节码。Java虚拟机是Java平台的一部分&#xff0c;Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...