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

news/2024/7/24 9:54:55 标签: 前端, typescript, javascript

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的时候,我们经常会类似下面的例子一样编写代码:👇👇👇

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

最后一行代码等价于:

typescript">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 类型的一个更具体的类型,所以它是一个字面量类型。

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

typescript">type Greeting = "Hello"

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

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

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

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

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

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

typescript">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:👇👇👇

typescript">interface Person {
    name: string
    age: number
    location: string
}

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

typescript">type SomeNewType = keyof Person

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

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

typescript">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 操作符。
但是,当我们不知道对象的类型,或者我们只有一个值,类似于下面的情况,应该怎么办呢?

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

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

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

typescript">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 时,它们会被转换为普通对象

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

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

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

typescript">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.niftyadmin.cn/n/233236.html

相关文章

0成本 使用home assistant远程开关机电脑

环境:dockerwin10HACS 问题:在外网手机上远程开关机家中电脑 解决办法:开机:WOL,关机ssh命令 背景:在部署HACS后,便想用HACS中的命令来开关机windows电脑,开机很简单,使用…

C++ 并发编程

文章目录基本概念编程创建线程启动共享数据相关条件变量时间相关future相关——等待一次性事件读写锁原子操作与缓存一致性关系线程管理启动线程从类的方法来创建线程传参标识线程常用API等待线程完成后台运行线程移动线程间共享数据互斥量(mutex)unique…

2023 GDOUCTF --- Crypto wp

文章目录CryptoAbsolute_Baby_EncrytpionbabyluaMagic of EncodingMath ProblemReCheck_Your_LuckCrypto Absolute_Baby_Encrytpion 将替换的字符反过来,然后把密文逐位解密拼接起来即可 encrypted_string }!q")hiim)#}-nvm)i-$#mvn#0mnbm)im#n}!qnm8)i-$#mvnoc#0nz&l…

[设计模式] --- 适配器模式

1 适配器模式简介 适配器模式是一种常用的设计模式,用于将一个类的接口转换成客户端所期望的另一种接口。适配器模式通常用于解决以下问题: 将现有类与新的代码进行集成。当我们需要在现有代码中使用新的类或库时,适配器模式可以帮助我们将…

解决 Docker + selenium + chromedriver + chrome 会出现僵尸进程的问题

一、僵尸进程问题 在docker里,使用selenium爬虫, webdriver quit后,会产生很多僵尸进程。docker run -it -v /home/blackip:/home/blackips/ selenium:1.0python3 linux_black_ip.pytop查看僵尸进程:ps -ef | grep defunct查看…

互联网摸鱼日报(2023-04-17)

互联网摸鱼日报(2023-04-17) InfoQ 热门话题 马斯克创建新的AI公司,与OpenAI 竞争 Uber实践:运维大型分布式系统的一些心得 马斯克爆料Twitter裁了八成员工;OpenAI推出漏洞赏金计划,奖励最高2万美元&…

substrate中打印调试信息的多种方式详解

目录1. 获取substrate-node-template代码2. 添加一个用于测试的pallet至依赖到pallets目录3. log方式来输出信息3.1 将log依赖添到cargo.toml文件3.2 log-test/src/lib.rs修改call方法3.3 polkadot.js.调用测试函数do_something_log_test4. printable trait方式来输出信息4.1 首…

网盘工具助力律师团队文件管理

律师的日常工作离不开文件管理。文档管理对于律师而言是一门必修课,这也是日积月累的工作。良好的文件管理习惯可以帮助我们让工作流程化、标准化,助力知识管理,避免职业风险,提升团队工作效率。 好用的文件管理工具也可以帮助律师…