一篇文章让你搞懂TypeScript中的typeof()、keyof()是什么意思

news2024/11/25 12:30:37

TypeScript中的typeof()、keyof()是什么意思?

  • 知识回调(不懂就看这儿!)
  • 场景复现
  • 核心干货👇👇👇
    • 举例引入
    • 字面量类型(literal types)
    • keyof单独使用
    • keyof typeof同时使用
    • 在enum上使用keyof typeof

知识回调(不懂就看这儿!)

知识专栏专栏链接
TypeScript知识专栏https://blog.csdn.net/xsl_hr/category_12030346.html?spm=1001.2014.3001.5482

在这里插入图片描述

有关TypeScript的相关知识可以前往TypeScript知识专栏查看复习!!

场景复现

最近在前端的深入学习过程中,接触了与网络请求相关的内容,于是计划用三个专栏(HTTPAxiosAjax)和零碎文章总结记录最近的学习笔记。由于项目前端技术栈的脚本语言为TypeScript,在研读小程序异步请求封装部分的代码时,碰到了几个关于TypeScript的小知识点不太清楚。

问题代码截图:
在这里插入图片描述

因此,本文以 TypeScript中的typeof()keyof() 为主要内容展开讲解。

核心干货👇👇👇

举例引入

在使用TypeScript的时候,我们经常会类似下面的例子一样编写代码:👇👇👇

// 定义一个枚举类型的对象
enum ColorsEnum {
    white = '#ffffff',
    black = '#000000',
}
// 定义Colors类型 里面的值只能是ColorsEnum中的值
type Colors = keyof typeof ColorsEnum;

最后一行代码等价于:

type Colors = "white" | "black" // Colors的值只能是“white”和“black”中的一个

那么其中keyof typeof是如何工作的呢?下面我们开始切入正题,开始详细讲述。


想要理解TypeScript里的keyof typeof是如何工作的,首先需要理解什么是“字面量类型(literal types)”和“联合字面量类型(union of literal types)”,下面我们来解释一下这两个概念,再来详细介绍keyoftypeof,最后回到enum来回答上面的问题。

字面量类型(literal types)

Typescript 中的字面量类型是更具体的 string, numberboolean 类型。比如 "Hello World" 是一个 string,但是 string 类型不是 "Hello World""Hello World"string 类型的一个更具体的类型,所以它是一个字面量类型。

一个字面型变量可以这样被定义:

type Greeting = "Hello"

这意味着 Greeting 类型的对象只能有一个字符串值 "Hello",并且没有其他 string 类型的值,或者其他任何类型的值,就像是下面代码说的一样:

let greeting: Greeting
greeting = "Hello" // OK
greeting = "Hi"    // Error: Type '"Hi"' is not assignable to type '"Hello"'

字面量类型本身并不是很有用,但是当它和联合类型(union types)、类型别名(type aliases)、类型保护(type guards)组合起来后,它就会变得很强大。

下面是联合字面量类型的例子:👇👇👇

type Greeting = "Hello" | "Hi" | "Welcome"

现在 Greeting 类型对象的值可以是 "Hello", "Hi" 或者 "Welcome"

let greeting: Greeting
greeting = "Hello"       // OK
greeting = "Hi"          // OK
greeting = "Welcome"     // OK
greeting = "GoodEvening" // Error: Type '"GoodEvening"' is not assignable to type 'Greeting'

keyof单独使用

假设现在有一个类型 T(泛型),keyof T 将会给你一个新类型,它是我们前面提到的联合字面量类型,并且组成它的字面量类型是 T 的属性名称。最后生成的类型是字符串的子类型

比如来看下下面的 interface:👇👇👇

interface Person {
    name: string
    age: number
    location: string
}

在 Person 类型上使用 keyof,将会得到一个新类型,如下面代码所示:👇👇👇

type SomeNewType = keyof Person

SomeNewType 是一个联合字面量类型("name" | "age" | "location"),它是由 Person 的属性组成的类型。

现在,你可以创建 SomeNewType 类型的对象了:👇👇👇

let newTypeObject: SomeNewType

newTypeObject = "name"           // OK
newTypeObject = "age"            // OK
newTypeObject = "location"       // OK
newTypeObject = "anyOtherValue"  // Error...Type '"anyOtherValue"' is not assignable to type 'keyof Person'

keyof typeof同时使用

typeof 运算符为你提供对象的类型,上面例子中 Person interface,我们已经知道它的类型,所以我们只需要在 Person 上使用 keyof 操作符。
但是,当我们不知道对象的类型,或者我们只有一个值,类似于下面的情况,应该怎么办呢?

const bmw = { name: "BMW", power: "1000hp" }

这就是我们需要一起使用 keyof typeof 的地方。typeof bmw 给到你他们的类型 { name: string, power: string }

接着 keyof 操作符给到你联合字面量类型,像下面代码描述的一样:👇👇👇

type CarLiteralType = keyof typeof bmw

let carPropertyLiteral: CarLiteralType
carPropertyLiteral = "name"       // OK
carPropertyLiteral = "power"      // OK
carPropertyLiteral = "anyOther"   // Error...Type '"anyOther"' is not assignable to type '"name" | "power"'

在enum上使用keyof typeof

在 Typescript 中,enum 在编译时被用作类型,用来实现常量的类型安全,但是它们在运行时被视为对象。这是因为,当 Typescript 代码被编译为 Javascript 时,它们会被转换为普通对象

接着我们回顾一下,最开始我们提出问题的例子是这样的:👇👇👇

enum ColorsEnum {
    white = '#ffffff',
    black = '#000000',
}

这里 ColorsEnum 在运行时作为一个对象存在不是一个类型,所以,我们需要一起使用 keyof typeof 这两个操作符,像下面代码展示的一样。

type Colors = keyof typeof ColorsEnum

let colorLiteral: Colors
colorLiteral = "white"  // OK
colorLiteral = "black"  // OK
colorLiteral = "red"    // Error...Type '"red"' is not assignable to type '"white" | "black"'

以上就是关于==TypeScript中的typeof()、keyof()==的分享,相信看完这篇文章的小伙伴们一定有了一定的收获。当然,可能有不足的地方,欢迎大家在评论区留言指正!

感兴趣的小伙伴可以订阅本专栏,方便后续了解学习~
觉得这篇文章有用的小伙伴们可以点赞➕收藏➕关注哦~

在这里插入图片描述

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

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

相关文章

AC7811电机驱动方案—电路分析

目录 电源树 12V转5V 输出电压设计 电感的选取 欠压锁定 电容的选取 PCB布局 5V转3.3V 输出噪声 外部反向电压保护 接口电路设计 USB转串口 JTAG 驱动电路 驱动桥电路 采样回路设计 电源树 12V转5V 使用了MPQ4420作为电压转换芯片。 芯片手册经典应用 输出电…

Kafka——概述、安装及命令行操作

文章目录一、概述1.1、定义1.2、如何运作?1.3、传统消息队列的应用场景1.4、消息队列的两种模式1.5、Kafka的基础架构二、安装(需要安装zookeeper)三、常用命令行操作3.1、主题命令行操作3.2、生产者命令行操作3.3、消费者命令行操作一、概述…

Python操作MySQL就是这么简单

Python操作MySQL就是这么简单下载MySQL 8.0安装MySQL 8.0步骤2:选择安装类型步骤3:选择安装位置步骤4:配置MySQL 8.0步骤5:安装MySQL 8.0步骤6:完成安装启动MySQL 8.0MySQL 8.0的常用命令python的 pymysql库操作方法安…

【C++】哈希的应用 -- 位图

文章目录一、位图的引入二、位图的实现三、bitset四、位图的应用五、哈希切割一、位图的引入 我们通过一道面试题来引入位图: 给定40亿个不重复的无符号整数,且没排过序,现在给一个无符号整数,如何快速判断一个数是否在这40亿个数…

ChatGPT想干掉测试人员,做梦去吧

很多人都发现ChatGPT可以做一些代码相关的工作,不仅可以写一些测试用例和自动化脚本,还可以做一定量的调优,于是就开始担忧起来,到哪天我的测试工作会不会被ChatGPT这个工具给取代了? 1. ChatGPT目前对哪些东西会有冲击…

Java:Arrays类

1、Arrays是啥&#xff1f; 数组操作工具类&#xff0c;专门用于操作数组元素的。 2.Arrays类的常用API 方法说明public static String toString(类型[] a)对数组进行排序public static void sort(类型[] a)对数组进行默认升序排序public static <T> void sort(类型[]…

图像分割——交叉熵损失

一、前言 写这篇博客的目的主要有两点&#xff0c;首先一点就是&#xff0c;以为对于交叉熵学过就会了&#xff0c;当初笔记也没有详细写过&#xff0c;但今天看论文发现里面的公式没有看懂才发现自己了解的还不够&#xff0c;平时用也是直接用的框架&#xff0c;原来一直认为会…

Java基础--数据结构

阅读目录 目录 数据结构 Java 集合框架 List Set Map 数据结构 Java工具包提供了强大的数据结构。在Java中的数据结构主要包括以下几种接口和类&#xff1a; 枚举&#xff08;Enumeration&#xff09;、位集合&#xff08;BitSet&#xff09;、向量&#xff08;Vector&a…

进阶C语言:程序环境和预处理

有关C语言的知识马上就要结束了&#xff0c;在学完了前面的基础之上我们就来深究一下程序底层的逻辑&#xff0c;关于程序的预处理编译指令&#xff0c;话不多说&#xff0c;我们直接开始&#xff1a; 目录 1.程序的翻译环境和执行环境 2. 详解编译链接 2.1翻译环境 2.2编译…

IT培训有靠谱的机构吗,长什么样的?

关于IT培训的问题&#xff0c;网上有一大波劝退的声音&#xff1a;现在的IT越来越卷&#xff0c;高校计算机专业毕业生每年那么多&#xff0c;作为小白转行的你竞争力又在哪里呢&#xff1f;而且去年互联网大厂那么多裁员&#xff0c;还有大幅度降薪等等&#xff0c;IT行业已经…

通达信破底翻选股公式,用缠论底分型进行优化

上次在写《通达信破底翻形态选股公式&#xff0c;选出破底之后再翻回的股票》这篇文章时&#xff0c;编写破底翻选股公式就考虑使用缠论底分型&#xff0c;但是底分型的包含关系较为复杂&#xff0c;不容易处理&#xff0c;只能暂时搁置&#xff0c;采用了一种简单的方式&#…

【PyTorch】第九节:Softmax 函数与交叉熵函数

作者&#x1f575;️‍♂️&#xff1a;让机器理解语言か 专栏&#x1f387;&#xff1a;PyTorch 描述&#x1f3a8;&#xff1a;PyTorch 是一个基于 Torch 的 Python 开源机器学习库。 寄语&#x1f493;&#xff1a;&#x1f43e;没有白走的路&#xff0c;每一步都算数&#…

低延迟流式语音识别技术在人机语音交互场景中的实践

美团语音交互部针对交互场景下的低延迟语音识别需求&#xff0c;提出了一种全新的低出字延迟流式语音识别方案。本方法将降低延迟问题转换成一个知识蒸馏过程&#xff0c;极大地简化了延迟优化的难度&#xff0c;仅通过一个正则项损失函数就使得模型在训练过程中自动降低出字延…

靶机精讲之Holynix

找不到ip 就设置两个网络适配器 再添加一个NAT 主机发现 nmap扫描 端口扫描 UDP扫描 服务扫描 脚本扫描 拒绝服务攻击 sql注入 枚举 web渗透 sql注入 证明有注入 sql注入语句 语句 ‘ or 11 --&#xff08;空格&#xff09; 目录结构像有文件包含 有报错但无法利用 调用系统…

从零开始学架构-计算高性能

一、概述 高性能是每个程序员的追求&#xff0c;无论做一个系统、还是写一组代码&#xff0c;都希望能够达到高性能的效果。而高性能又是最复杂的一环&#xff0c;磁盘、操作系统、CPU、内存、缓存、网络、编程语言、数据库、架构等&#xff0c;每个都可能影响系统的高性能&…

ChatGPT API接口使用+fine tune微调+prompt介绍

目录1 接口调用1.1 生成key1.2 接口功能1.2.1 图片生成 (image generation)1.2.2 对话(chat)1.2.3 中文纠错 (Chinese Spelling Correct)1.2.4 关键词提取 &#xff08;keyword extract)1.2.5 抽取文本向量 (Embedding)1.2.6 微调 (fine tune)2 如何写好prompt2.1分类任务2.2 归…

工业智能网关应用场景:高层楼宇智慧消防解决方案

随着城市化建设的飞速发展&#xff0c;人员聚集与土地资源稀缺的矛盾越来越明显。为了让有限的空间满足更多人的居住需求&#xff0c;高层楼宇越来越多&#xff0c;对于安全消防形成更大的挑战。 基于物联网和云计算平台的智慧消防在消防管理、火灾报警和实时监管方面发挥越来…

java内部类入门(接口)

我有一个玩具狗&#xff0c;有一个接口用于启动它&#xff0c;按照传统方法就是写一个类并实现该接口&#xff0c;且该类只使用一次&#xff08;在启动时使用&#xff0c;后面再不使用&#xff09; 但是如果我有一堆玩具&#xff0c;我每个玩具都要去写一个类来实现start这个接…

GPT-3.5还没研究明白,GPT-4又来了,chatGPT会进化成什么样?

基于GPT-3.5的chatGPT热度才稍稍减退没多久&#xff0c;GPT-4又来了&#xff0c;文新一言的发布会也槽点满满&#xff0c;差距似乎越来越大了。 chatGPT到底厉害在哪&#xff1f;为什么突然就爆火了呢&#xff1f; 它的爆火&#xff0c;一方面&#xff0c;和它的出现形态有关…

代码随想录第18天 | 530.二叉搜索树的最小绝对差 501.二叉搜索树中的众数 236. 二叉树的最近公共祖先

530.二叉搜索树的最小绝对差 var getMinimumDifference function (root) {//中序遍历法&#xff1a;左中右let res []if (!root) return res;const st [root] //栈&#xff0c;pop(),push()while (st.length) {let x st.pop()if (!x) {res.push(st.pop().val)continue}if (…