如何在 TypeScript 中索引对象类型?

2023-11-30

我的应用程序收到“消息”。我首先验证未知输入以确保它遵循预期的消息格式:

const isMessage = x => 
  typeof x === 'object' && 
  x !== null && 
  typeof x['data'] === 'string';

我希望在 TypeScript 中输入此内容。这是我所拥有的:

type Message = { data: string };

const isMessage = (x: unknown): x is Message => 
  typeof x === 'object' && 
  x !== null && 
  typeof x['data'] === 'string';

但是,这无法进行类型检查,因为:

Element implicitly has an 'any' type because expression of type '"data"' can't be used to index type '{}'.
  Property 'data' does not exist on type '{}'.

类型保护之后typeof x === 'object' && x !== null, TypeScript 给出输入x : object。这似乎与x : {}。但这种类型不允许我检查对象的任何属性。

代替x: object,我想我想要一个“字典”类型,例如x: { [key: string | number | symbol]: unknown }。但这不是 TypeScript 从类型保护中给我的输入typeof x === 'object'.

我可以用as铸造x到字典类型:

const isMessage = (x: unknown): x is Message => 
  typeof x === 'object' && 
  x !== null && 
  typeof (x as { [key: string | number | symbol]: unknown })['data'] === 'string';

这种类型检查,但它真的又长又笨拙,而且我不确定as类型转换确实是类型安全的。

我读到了关于in算子缩小,基于此,我预计添加'data' in x会工作:

const isMessage = (x: unknown): x is Message => 
  typeof x === 'object' && 
  x !== null && 
  'data' in x &&
  typeof x['data'] === 'string';

然而,这没有什么区别; TypeScript 仍然抱怨我无法索引x,即使在某个点'data' in x。为什么会这样in运算符不允许我索引x?


你应该能够这样做:

type Message = { data: string };

const isMessage = (x: unknown): x is Message => 
  typeof x === 'object' && 
  x !== null && 
  typeof (x as Message).data === 'string';

TypeScript 的文档中展示了该技术:https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates


Since typeof也是一个runtime检查as断言不会消除任何类型安全性。

你可以这样想:在最后一行之前,我们已经检查过x是一个对象并且不是null. So, x.data即使在运行时也不会失败x将会{} or {bar: 'bar'} or {data: null}。我们只需要使用断言来让编译器允许我们做运行时的事情typeof check.

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

如何在 TypeScript 中索引对象类型? 的相关文章

随机推荐

  • 如何在 Jupyter Lab 中打开调试器按钮

    我正在使用 jupyter lab 并尝试嵌入debugger in it Windows 10 64 bit 以下是我遵循的步骤 conda create name ml python 3 8 2 conda activate ml co
  • 使用 Chef 在 Windows 节点上挂载 Windows 共享

    我正在尝试将文件从 Windows 共享复制到我的节点的缓存 显然没有办法从remote file 做到这一点 所以我的替代想法是尝试将Windows 共享安装到本地驱动器并通过文件资源访问我需要的文件 然而 即使 Chef 告诉我挂载成功
  • 如何在 Eclipse 中使用调试视角。[调试 java/j2ee 应用程序]

    是否有任何易于遵循的教程来在 Eclipse 中调试 Java J2EE 应用程序 有关如何检查未检查和已检查异常的分步指南 我一直试图在互联网上寻找 但没有用 要添加 Java 异常断点 在 调试 透视图中选择 断点 视图 然后单击异常断
  • ip地址和mac地址的正则表达式

    谁能建议我 ip 地址和 mac 地址的正则表达式 我正在使用 python 和 django 例如 http ip地址 SaveData 127 0 0 1 00 0C F1 56 98 AD 对于 mac 地址 我尝试遵循但没有成功 0
  • 以 boost 精神实现运算符优先级

    我试图复制这个例子为了实现类似 C 的运算符优先级规则 我从一个子集开始 但最终计划添加其他子集 尽我所能 我无法获得解析单个二进制操作的语法 它可以很好地解析文字 44 3 42 stackoverflow 但会失败 例如3 4 我确实看
  • 通过 Selenium 运行测试用例时出现 java.lang.NullPointerException

    我面临 NullPointerException 的问题 我尽了最大努力 但无法解决这个问题 我正在为我的项目实现 POM 模型 Selenium 这一页 public class VendorsHomePageApp WebDriver
  • 用科学记数法写json float

    我想使用 Python 3 6 以科学记数法表示 JSON 文件中的浮点数 没有 import json a 0 001234567 print json dumps a json encoder FLOAT REPR lambda x e
  • 如何防止 Android 设备在插入电源时进入睡眠状态

    我希望每当我的一项活动正在运行并且手机插入电源时都保持屏幕打开 我知道唤醒锁很棘手 因此我正在寻找有关如何实现此特定目标的示例或一些文档 不要为此使用唤醒锁 只需设置和清除窗口标志WindowManager LayoutParams FLA
  • 在Python中的嵌套字典中添加键

    elements hydrogen number 1 weight 1 00794 symbol H helium number 2 weight 4 002602 symbol He Add an is noble gas氢和氦字典的布尔
  • QFileSystemModel 自定义图标?

    在我的项目中 我有一个 QTreeView 显示我的驱动器上的位置 我需要将文件的所有图标更改为自定义图标 但保留文件夹 我重新实现了 QFileSystemModel 并且能够更改所有图标 有什么方法可以限制仅更改文件而不是文件夹吗 QV
  • 我怎样才能知道 JSF 组件的 id 以便在 Javascript 中使用

    Problem 有时你会想从 javascript 访问一个组件getElementById 但是 id 是在 JSF 中动态生成的 所以你 需要一种获取对象 ID 的方法 我在下面回答了如何做到这一点 原问题 我想使用如下代码 如何在 J
  • 无法更新数据库“*.mdf”,因为只读 EntityFramework

    我有一个 C NET Framework 4 0 桌面应用程序 其中实体框架作为 DAL 当尝试将数据保存到除我之外的任何人的机器上的 DBContext 时 我收到了一个异常 Failed to update database mdf r
  • 属性和多态性

    我有两节课 public class Increase public int a 3 public void add a 5 System out println f class SubIncrease extends Increase p
  • R 中的行相关

    我有两个相同大小的矩阵 我想计算这些矩阵中每对行之间的相关系数 A 的第 1 行与 B 的第 1 行 A 的第 2 行与 B 的第 2 行 等等 A lt matrix runif 1 200 nrow 20 B lt matrix run
  • 在 Android 中使用通过 OTG 线连接的 USB 播放视频?

    我想问是否有可用的应用程序 用户可以通过 OTG 电缆设备将 USB 连接到 Android 并播放其中包含的媒体 特别是视频 我制作了一个广播接收器来检测连接的 USB 我也想读取内容 我正在使用这个代码片段 private final
  • 多层应用程序数据文件夹 - Windows 7

    在命令窗口中 如果我导航到 c users me 并执行 dir 我会看到 13 个文件夹 但没有文件 如果我执行 dir s 我会看到数千个文件 但令我困扰的是我看到这样的路径 C Users me AppData Local Appli
  • 异步 https firebase 函数

    HTTPS 函数是否应该像实时函数那样返回异步承诺 我们还没有返回 HTTPS 函数 仅使用 res status send 等 而且看起来 firebase function samples 也没有返回 但文档有点含糊https fire
  • 从 Excel 调用具有多个参数的存储过程

    我已经建立了 SQL Server 与存储过程所在数据库的连接 存储过程在 SQLServer 中运行良好 存储过程通过与 Excel 中的硬编码参数的连接运行得很好 我得到了我的数据集并将其插入到我的电子表格中 宏不起作用 在宏中 我尝试
  • 如何将 YAML 拆分为多个具有正确名称的文件

    我有一个有效的 YAML name first metadata a name second metadata b name third metadata c 如何在文件中使用单行 AWK 脚本拆分它first yaml second ya
  • 如何在 TypeScript 中索引对象类型?

    我的应用程序收到 消息 我首先验证未知输入以确保它遵循预期的消息格式 const isMessage x gt typeof x object x null typeof x data string 我希望在 TypeScript 中输入此