TypeScript 中的“keyof typeof”是什么意思?

2023-12-10

向我解释一下什么keyof typeof在 TypeScript 中的意思是

Example:

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

type Colors = keyof typeof ColorsEnum;

最后一行相当于:

type Colors = "white" | "black"

但它是如何运作的呢?

我希望typeof ColorsEnum返回类似的东西"Object"进而keyof "Object"不做任何有趣的事情。但我显然错了。


要了解keyof typeof在 TypeScript 中的用法,首先你需要了解什么是文字类型 and 文字类型的联合。所以,我会先解释这些概念,然后再解释keyof and typeof分别详细说明。之后我会回来enum回答问题中提出的问题。这是一个很长的答案,但示例很容易理解。


文字类型

TypeScript 中的文字类型是更具体的类型string, number or boolean。例如,"Hello World" is a string, but a string is not "Hello World". "Hello World"是一种更具体的类型string,所以它是一个文字类型。

文字类型可以声明如下:

type Greeting = "Hello"

这意味着该类型的对象Greeting只能有一个string value "Hello"没有其他stringvalue 或任何其他类型的任何其他值,如以下代码所示:

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

文字类型本身并没有什么用处,但是当与联合类型、类型别名和类型保护结合使用时,它们就会变得强大。

以下是一个示例文字类型的联合:

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

现在类型的对象Greeting可以有值"Hello", "Hi" or "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 only

keyof某种类型的T给你一个新的类型文字类型的联合这些文字类型是属性的名称T。结果类型是字符串的子类型。

例如,考虑以下情况interface:

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

使用keyof类型上的运算符Person将为您提供一个新类型,如以下代码所示:

type SomeNewType = keyof Person

This SomeNewType是文字类型的联合 ("name" | "age" | "location") 由类型的属性组成Person.

现在您可以创建类型的对象SomeNewType:

let newTypeObject: SomeNewType
newTypeObject = "name"           // OK
newTypeObject = "age"            // OK
newTypeObject = "location"       // OK
newTypeObject = "anyOtherValue"  // Error...

keyof typeof一起在一个物体上

您可能已经知道,typeof运算符给出对象的类型。 在上面的例子中Person接口,我们已经知道类型,所以我们只需要使用keyof类型运算符Person.

但是,当我们不知道对象的类型或者我们只有一个值而不是该值的类型时该怎么办,如下所示?

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

这是我们使用的地方keyof typeof一起。

The typeof bmw给你类型:{ name: string, power: string }

进而keyof运算符为您提供文字类型联合,如以下代码所示:

type CarLiteralType = keyof typeof bmw

let carPropertyLiteral: CarLiteralType
carPropertyLiteral = "name"       // OK
carPropertyLiteral = "power"      // OK
carPropertyLiteral = "anyOther"   // Error...

keyof typeof on an enum

在 TypeScript 中,枚举用作编译时的类型实现常量的类型安全,但它们被视为运行时的对象。这是因为,一旦 TypeScript 代码被编译为 JavaScript,它们就会转换为普通对象。因此,上述对象的解释也适用于这里。 OP在问题中给出的例子是:

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

Here ColorsEnum在运行时作为对象而不是类型存在。所以,我们需要调用keyof typeof运算符组合在一起,如以下代码所示:

type Colors = keyof typeof ColorsEnum

let colorLiteral: Colors
colorLiteral = "white"  // OK
colorLiteral = "black"  // OK
colorLiteral = "red"    // Error...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TypeScript 中的“keyof typeof”是什么意思? 的相关文章

随机推荐

  • Unity - 通过 XML 的工厂

    我使用 Unity 框架作为 IoC 容器 我的配置看起来像这样
  • 如何在 Javascript 中重新加载页面而不出现 POSTDATA 警告?

    我想使用以下方法重新加载页面 window location reload true 但我收到 POSTDATA 警告 因为刷新功能想要重新发送以前的 POST 表单数据 如何刷新页面而不出现此警告 更新 我无法控制该项目 我无法解决 PO
  • 相对于(也是绝对定位的)父 DIV 的绝对定位 DIV 的位置?

    这是我在修复布局时经常遇到的一个问题 我有一个绝对定位的 DIV 我在里面放置了一个子 DIV 它也需要绝对定位 但我真的希望这个子 DIV 相对于父级的行为 这可能吗 或者我需要创建一个wrap DIV div class contain
  • Protractor如何测试select2

    我有一个 select2 下拉菜单 您需要先输入 2 个字符 然后选择您的项目 我无法用量角器对此进行测试 var select2 element by css div s2id person select2 click select2 s
  • PHP中检查字符串的第一个字符是字母还是数字? [复制]

    这个问题在这里已经有答案了 有没有办法检查字符串的第一个字符是字母还是数字 我不太确定该使用什么功能 有没有办法检查不使用正则表达式 因为我们在课堂上还没有学到这一点 我鼓励您阅读更多有关PHP 中的字符串 例如 您可以像数组一样取消引用它
  • JDBC 中的 Java 类型到 Postgres ltree

    有谁知道什么 Java 类型映射到 Postgres ltree 类型 我创建一个像这样的表 CREATE TABLE foo text name path ltree 一些插入 INSERT INTO foo name path VALU
  • 在 HTML 中使用内联事件处理程序是一种不好的做法吗? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 使用内联 JavaScri
  • MySQL全文搜索总是有0个结果?

    我读到使用全文搜索比使用 LIKE 更快 我已经更新了我的脚本 但它似乎总是有 0 结果 SELECT MATCH pages AGAINST doodle AS score FROM books WHERE MATCH pages AGA
  • 通过 exec() 从 php 调用 php 没有结果

    我有一个 PHP 脚本 可以根据用户输入创建其他 PHP 文件 基本上 有一些文件包含特定于语言的常量 define 可由用户翻译 为了避免运行时错误 我想测试新编写的文件是否存在解析错误 由于 不寻常 的字符序列 我在这里读过几篇关于SO
  • 将 ImageSharp 作为字段添加到 MarkdownRemark 节点(不是 frontmatter)

    我正在尝试执行以下 graphQL 查询 allMarkdownRemark limit 1000 edges node id parent id fields slug hero childImageSharp fixed src
  • 文本前后的行没有响应[重复]

    这个问题在这里已经有答案了 我试图在文本之前和之后各添加一行 但我希望它能够响应 目前我能找到的唯一方法是使用宽度 所以它不响应 我更愿意仅在伪元素之前和之后使用 但如果不可能 那么我会发现另一种方法 HTML div class sect
  • 将文件输出存储到变量中

    我想将文本文件的输出存储到一个变量中 这样我就可以将整个文件作为参数传递 我使用的是Windows 2003 Server 文本文件有多行 例如 10 20 210 100 fish 10 20 210 101 rock 我正在使用 Set
  • Android:如何检查是否启用了特定的 AccessibilityService

    我编写了一个 Android 应用程序 需要使用AccessibilityService 我知道如何检查手机上是否启用或禁用了辅助功能 但我无法找到一种方法来确定我的应用程序是否已在辅助功能菜单中专门启用 我想提示用户如果Accessibi
  • Scanf 将输入的字符串解析为字符数组

    我想在两个单独的数组中解析用户输入 使用 scanf g 编译没有错误 但出现内存访问错误 核心转储 德语 Speicherzugriffsfehler Speicherabzug geschrieben char top 10 char
  • Firebase 按字符搜索

    我在我的 firebase 应用程序中使用 FirebaseRecyclerAdapter 直到现在我仍然不知道如何在 Firebase 中按字符搜索 我已经使用了查询 并且得到了很好的结果 但它不可用 这是我想要的数据库搜索 这是我使用它
  • Excel 中的排列

    我有一个有 6 个空格的字符串 例如000000 每个空格可以容纳三位数字之一 0 1 或 2 我知道使用 Excel 中的 Permut 函数总共可以获得 120 种排列 即 PERMUT 6 3 120 但我会实际上喜欢在单元格中进行每
  • C# 相对路径不从工作目录开始

    我有一个 C 程序 它将从相对路径读取文件 report report1 rdlc 但是有时由于未知原因它从完全不同的位置找到了该文件C Windows system32 report report1 rdlc但该文件实际上位于C Prog
  • 客户端的 ASP.NET MVC 多对多模型

    我有 3 个多对多表 Users lt UserRoles gt Roles 我这样设置我的模型 public class User public int UserId get set public IEnumerable
  • 设置 JetBrains YouTrack 以连接到 SVN

    我意识到 TeamCity 一定是 YouTrack 和 SVN 之间的桥梁 但我不需要 Teamcity 的任何功能 我只想通过提交评论发出 Youtrack 命令像这儿 http confluence jetbrains net dis
  • TypeScript 中的“keyof typeof”是什么意思?

    向我解释一下什么keyof typeof在 TypeScript 中的意思是 Example enum ColorsEnum white ffffff black 000000 type Colors keyof typeof Colors