在 TypeScript 中有效地使用 keyof 和 typeof 来表示类型

在本文中,我们将学习如何通过组合类型运算符和枚举来提取和声明常量类型typeof,以使您的代码库得到优化。keyof

先决条件

为了获得更好的编码体验,您应该在 IDE 中安装 TypeScript,例如VSCode。它将为您提供许多基本功能,例如错误突出显示、IntelliSense、linting 等...您还应该安装一些扩展,例如JavaScript 和 TypeScript Nightly、ESLint等。

什么是typeof

在 TypeScript 中,我们可以用来typeof提取变量或属性的类型,如下例所示:

``` const Name = { firstName: 'Maya', lastName: 'Shavin' };

let myName: typeof Name; ```

在上面的代码中,我们使用myName从变量 中提取的类型来声明变量Name,这将是一个具有两个属性 -firstName和 的对象lastName。当鼠标悬停myName在 IDE 中时,TypeScript 将向您显示myName结论的类型Name,如以下屏幕截图所示:

显示名称类型的屏幕截图,其中名字和姓氏作为其属性

这里注意typeof,如果要提取类型的变量是一个 Object,那么接收到的类型将是一个完整的类型结构,并且每个属性都有其类型(例如 type of 将有myName两个字段 - firstNameof typestringlastNameof kind string)。

另一个有价值的场景typeof是将其与ReturnType从函数中提取返回数据的类型结合起来。为此,我们执行以下操作:

  1. 使用以下方法获取声明函数的函数类型typeof
  2. 使用ReturnType<T>withT是步骤 1 中提取的类型来获取 from 的返回值类型T

下面的例子演示了如何提取返回类型decoupleName()

``` function decoupleName (name: string) { const [firstName, ...remaining] = name.split(" ");

return {
    firstName,
    lastName: remaining.reduce((text, word) => text ? `${text} ${word}` : word, '')
}

}

type NameObj = ReturnType ```

TypeScript 将自动引用正确的类型NameObj,如下面的屏幕截图所示:

显示 NameObj 类型(其属性为名字和姓氏)的屏幕截图

此外,我们可以typeof在 TypeScript 中用作条件块内的类型保护,就像在 JavaScript 中一样,尽管在这种情况下,它主要适用于stringobjectfunction等基本类型...

现在我们了解了typeof它的用法。接下来我们就来探讨一下keyof

理解keyof

虽然typeof生成由变量表示的类型,但keyof采用对象类型并生成作为该变量键的自由联合的类型,如下所示:

``` interface User { firstName: string; lastName: string; };

type UserKeys = keyof User ```

以上等同于以下声明:

type UserKeys = "firstName" | "lastName"

但是,与 不同的是typeof,您不能keyof直接在变量上使用。对于以下代码,TypeScript 将引发错误:

``` const Name = { firstName: 'Maya', lastName: 'Shavin' };

type NameKeys = keyof Name; //error ```

要从对象变量(例如常量值的对象映射)中提取类型,我们需要结合keyoftypeof,我们接下来将学习这一点。

从对象的键(或属性)中提取typeOf

以下面的ImageVariables为例,它充当修改图像时使用的变量的映射:

export const ImageVariables = { width: 'w', height: 'h', aspectRatio: 'ar', rotate: 'a', opacity: 'o', } as const;

请注意,这里我们需要const对象末尾的 来将其指示为只读。否则,TypeScript 将不允许我们从中提取类型,因为存在随时修改对象内部属性的风险。

ImageVariables包含从其键到根据Cloudinary 机制转换图像时使用的匹配变量符号的映射。要根据 的属性(或键)生成类型ImageVariables,我们执行以下操作:

  1. ImageVariables获取代表使用的类型typeof

type ImageVariablesType = typeof ImageVariables

  1. 根据类型的键提取新类型ImageVariablesType,使用keyof

type ImageFields = keyof ImageVariablesType

或者,我们可以将上述两个步骤合二为一,如下所示:

type ImageFields = keyof typeof ImageVariables

就是这样。我们现在有了ImageFieldstype,其中包含 的接受字段ImageVariables,如下面的屏幕截图所示:

显示 ImageFields 类型的屏幕截图,其中 ImageVariables 的所有键作为其可接受的值

我们现在可以使用这个生成的类型,如下所示:

``` const transformImage = (field: ImageFields) => { const variable = ImageVariables[field]

//do something with it

} ```

通过基于 的属性声明类型ImageVariables,任何使用 的流程transformImage都是安全的,并且我们可以确保field传递的内容始终需要存在于 中ImageVariables。否则,TypeScript 将检测任何错误并向用户发出警报。

将 ImageFields 中不存在的值传递给函数 TransformImage 时,TypeScript 显示错误的屏幕截图

此外,Intellisense 将告知用户可接受的值,限制传递错误值的可能性。

显示接受值传递给transformImage的提示下拉列表的屏幕截图

顺便说一句,类型检查的行为与hasOwnProperty()运行时检查类似,尽管它只发生在编译时。

听起来很简单。如果我们想将键的值提取到ImageVariables新类型中怎么办?我们接下来看一下。

从对象的键(或属性)的值中提取typeof

如果我们想从 的键值生成一个类型ImageVariables,我们可以执行以下操作:

type VariableValues = typeof ImageVariables[ImageFields]

由于我们已经声明ImageVariablesType为 of 类型ImageVariables,因此我们可以将上面的内容重写为:

type VariableValues = ImageVariablesType[ImageFields]

通过上面的代码,我们现在有了一个新类型,VariableValues它接受以下值:

显示从 ImageVariables 键值生成的类型的屏幕截图

从命名常量对象的值和键生成类型在许多情况下都是有利的,例如当您必须使用各种数据映射并且标准键或值在它们之间进行映射时。在对象映射上使用keyoftypeof可以帮助创建相关映射和类型之间的连接,从而避免潜在的错误。

或者,我们可以结合枚举 和typeof来实现相同的目标。

使用枚举

枚举是声明命名常量类型的一种方便且有组织的方式。它允许我们创建一组不同的常量值,并且每个枚举字段都是基于数字或基于字符串的。我们可以重写我们ImageVariables的如下:

enum EImageVariables { width = 'w', height = 'h', aspectRatio = 'ar', rotate = 'a', opacity = 'o', }

使用枚举的优点之一是我们可以使用枚举的名称作为接受值声明的类型。因此,代替以下代码:

``` type VariableValues = typeof ImageVariables[ImageFields]

function transform(value: VariableValues) { //perform something } ```

EImageVariables我们可以使用如下方式重写:

function transform(value: EImageVariables) { //perform something }

对于更少的代码,类型检查执行相同的操作。尽管如此,为了从声明的 enum 的键(或属性)获取类型,我们仍然需要像常规常量对象一样EImageVariables使用组合:keyof typeof

type ImageFields = keyof typeof EImageVariables

就是这样。上面的代码产生的结果与我们使用ImageVariables.

现在让我们回顾一下如何从常量对象的键和值获取类型:

``` export const ImageVariables = { width: 'w', height: 'h', aspectRatio: 'ar', rotate: 'a', opacity: 'o', } as const;

type ImageVariablesType = typeof ImageVariables; type ImageFields = keyof ImageVariablesType; type VariableValues = ImageVariablesType[ImageFields]; ```

与使用枚举相比:

``` enum EImageVariables { width = 'w', height = 'h', aspectRatio = 'ar', rotate = 'a', opacity = 'o', }

type EImageVariablesType = typeof EImageVariables; type EImageFields = keyof EImageVariablesType; //No need for getting the type of values ```

与常量对象一样,我们可以直接使用枚举键的值,例如EImageVariables.width在我们的代码中。在运行时,枚举作为 JavaScript 对象存在于编译后的代码中,并且表现得像 JavaScript 对象。

一般来说,枚举是可以的。在 TypeScript 中,由于其实现方式效率低下(希望这个问题已得到修复或会很短),许多人认为它对性能有影响。

那么我们应该使用它们吗?这取决于。这个选择由你。

概括

在使用 TypeScript 时,我们经常忽略类型运算符,例如typeof或 ,keyof因为它们太初级了。然而,它们在构建类型系统中发挥着重要作用。当正确结合其他 TypeScript 语法时,它们可以帮助您的应用程序开发高级和复杂的类型。让我们尝试一下它们,看看它们能为您带来什么。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【论文导读】- Variational Graph Recurrent Neural Networks(VGRNN)

文章目录 文章信息摘要BackgroundGraph convolutional recurrent networks (GCRN)Semi-implicit variational inference (SIVI) Variational graph recurrent neural network (VGRNN)VGRNN modelSemi-implicit VGRNN (SI-VGRNN) 文章信息 Variational Graph Recurrent Neural …

STM32 串口代码配置

一、首先开发板上关于串口1的引脚配置已经配置好了&#xff0c;位置在SYSTEM的 usart.c 文件中&#xff08;注意&#xff1a;只配置了串口1的&#xff0c;其他使用时需要自己配置&#xff09; 重要的是明白配置的参数都是什么意思&#xff0c;针对实现不同的串口功能有什么影响…

选择高考志愿:聚焦计算机科学与技术,规避土木工程

选择高考志愿&#xff1a;聚焦计算机科学与技术&#xff0c;规避土木工程 高考季已至&#xff0c;各地高考成绩陆续公布&#xff0c;许多毕业生和家长开始面临疑惑&#xff1a;如何填报志愿、选专业还是选学校、什么专业好就业&#xff1f;张雪峰曾提到&#xff1a;“普通家庭…

从零开始 Spring Boot 60:一个实体映射到多个表

从零开始 Spring Boot 60&#xff1a;一个实体映射到多个表 图源&#xff1a;简书 (jianshu.com) 在之前的文章中我们讨论了 JPA 中的一对一关系&#xff0c;实际上存在一种特殊的一对一关系&#xff0c;即将一个实体映射到多张表&#xff0c;本文会讨论这种关系。 我之前提过…

如何将采购报价请求流程自动化?

在当今快节奏的商业环境中&#xff0c;效率和速度是保持竞争力的关键。在采购管理中&#xff0c;企业经常为简化操作而努力的一个领域是报价请求过程。手动处理请求、与供应商沟通并跟踪答复&#xff0c;可能非常耗时且容易出错。 然而&#xff0c;随着像8Manage SRM等专业电子…

Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库

介绍 Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库&#xff0c;基于 ECMA-376&#xff0c;ISO/IEC 29500 国际标准。可以使用它来读取、写入由 Microsoft Excel™ 2007 及以上版本创建的电子表格文档。支持 XLAM / XLSM / XLSX / XLTM / XLTX 等多种文档格式&a…

Git下载与安装(windows)

文章目录 Git 简介Git 下载Git 安装Git 环境变量配置 Git 简介 Git 是一种分布式版本控制系统&#xff0c;用于快速、高效地处理任何大小规模的项目。它是由 Linus Torvalds 在 2005 年开始开发的&#xff0c;Git 最初是为了管理 Linux 内核源代码而创建的。现在 Git 是一个广…

Spring 是什么框架?

对于一门技术&#xff0c;我们需要从为什么要学、学什么以及怎么学这三个方向入手来学习。那在说Spring这三点之前&#xff0c;我们先看Spring之前要学什么。 Java基础、Java语法进阶、MySQL基础操作、MySQL数据库设计和多表操作、JDBC、Maven基础、MyBatis、HMLCSS、JavaScrip…

PCA主成分分析

PCA降维算法 目前图像特征的提取主要有两种方法&#xff1a;传统图像特征提取方法 和 深度学习方法。 传统的特征提取方法&#xff1a;基于图像本身的特征进行提取&#xff08;PCA&#xff09;&#xff1b;深度学习方法&#xff1a;基于样本自动训练出区分图像的特征分类器&a…

SpringBoot--超时熔断器

需求背景 如果一个服务中有很多涉及需要服务间熔断的地方&#xff0c;就会出现N多下述代码&#xff1a; 1.N个fegnClient接口 FeignClient(name "hello-world-service", fallback HelloWorldFallback.class) public interface HelloWorldService {GetMapping(&q…

Python 学习之NumPy(一)

文章目录 1.为什么要学习NumPy2.NumPy的数组变换以及索引访问3.NumPy筛选使用介绍筛选出上面nb数组中能被3整除的所有数筛选出数组中小于9的所有数提取出数组中所有的奇数数组中所有的奇数替换为-1二维数组交换2列生成数值5—10&#xff0c;shape 为(3,5)的二维随机浮点数 NumP…

Apache Doris (十七) :Doris分区和分桶3-分桶及建议

​​​目录 一、分桶Bucket ​​​​​​​二、分区和分桶数量和数据量的建议 进入正文之前&#xff0c;欢迎订阅专题、对博文点赞、评论、收藏&#xff0c;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; 一、分桶Bucket Doris数据表存储中&#xff0c;如果有分区&…

使用docker搭建mysql集群

一、技术架构 1、架构图 2、解说 mysql_1、mysql_2、mysql_3是一组主从模式,同理mysql_4、mysql_5、mysql_6也是一组主从模式从上面的图可以看出mysql_1和mysql_4是主节点,可以进行增删改查操作,但是子几点只能查询操作如果mysql_1节点出现问题了&#xff0c;有mysql_4节点组…

SDK和API是什么?SDK和API的区别与联系

目录 &#x1f48c; SDK和API是什么&#xff1f; SDK API &#x1f48c; SDK和API的区别 &#x1f48c; 该如何选择 API 和 SDK 对接&#xff1f; &#x1f48c; SDK和API是什么&#xff1f; SDK SDK的概念&#xff1a;软件开发工具包&#xff08;全称&#xff1a;Softwa…

黑盟菜鸟剪辑短视频助手是什么

今天我们来讲一下视频综合处理功能&#xff0c;首先我们来打开软件主界面&#xff0c;通过模块化功能合集视频综合处理进入我们的这个功能。首先我们来看一下功能的布局&#xff0c;左边是导入视频的地方&#xff0c;右边是功能区&#xff0c;这里总共包括 32 种功能&#xff0…

计算机基础--->数据结构(6)【AVL树(平衡二叉树)】

文章目录 AVL&#xff08;平衡二叉树&#xff09;树性质AVL树的操作&#xff08;Java&#xff09;节点的创建AVL树的插入1.判断平衡2.保持树的平衡3.判断是否AVL树4.删除节点 全部代码 AVL&#xff08;平衡二叉树&#xff09;树 平衡二叉树是一种特殊的二叉搜索树&#xff0c;他…

【nav_msgs/Path.h发布路径】

#include <nav_msgs/Path.h> 是一个 ROS (Robot Operating System) 中的包含文件。它是用于包含 nav_msgs/Path 消息类型的头文件,这是一个标准的 ROS 消息类型。 nav_msgs/Path 消息类型常用于机器人导航系统中,以表示路径。这种路径通常由一系列的位置点组成,这些点…

解决:yarn 无法加载文件 “C:\Users\admin\AppData\Roaming\npm\yarn.ps1,因为在此系统上禁止运行脚本“ 的问题

1、问题描述&#xff1a; 其一、报错的整体代码为&#xff1a; yarn : 无法加载文件 C:\Users\admin\AppData\Roaming\npm\yarn.ps1&#xff0c;因为在此系统上禁止运行脚本 // 整体的报错代码为 &#xff1a; yarn : 无法加载文件 C:\Users\admin\AppData\Roaming\npm\yar…

Linux环境搭建(三)— 搭建数据库服务器

linux &#xff08;ubuntu&#xff09;安装mysql 和环境配置 一、安装MySql二、配置环境三、外网访问四、重置密码五、卸载 写在前面&#xff1a; 本文默认你的Linux系统已经安装vim&#xff0c;yum等&#xff0c;如你使用的是一个全新的操作系统&#xff0c;移步上一篇开始配置…

迪赛智慧数——柱状图(象形动态图):高考填报专业考虑的因素

效果图 填报志愿是高考后的一大重要环节&#xff0c;你的职业生涯就在这里起航了。那么&#xff0c;应该怎么填报志愿呢&#xff1f;高考填报专业考虑的因素很多&#xff0c;过半的人会考虑专业就业前景及薪资&#xff0c;其次是个人兴趣和是否为双一流建设学科。 数据源&…