当前位置:首页 > 科技  > 软件

TypeScript中遍历对象键的方法

来源: 责编: 时间:2023-11-28 17:11:24 367观看
导读前言在日常的TypeScript开发中,经常需要遍历对象的键来执行各种操作。然而,使用Object.keys时可能会遇到一些类型相关的困扰,因为它返回的是一个字符串数组,而不是期望的键的联合类型。这可能导致在代码中引入一些不安全

前言

在日常的TypeScript开发中,经常需要遍历对象的键来执行各种操作。然而,使用Object.keys时可能会遇到一些类型相关的困扰,因为它返回的是一个字符串数组,而不是期望的键的联合类型。这可能导致在代码中引入一些不安全的类型转换。在本文中,我们将深入研究这个问题,并提供几种解决方案,以便在遍历对象键时更安全、更灵活地操作。jCe28资讯网——每日最新资讯28at.com

背景

使用Object.keys进行遍历并不能按照预期工作。这是因为Object.keys返回一个字符串数组,而不是包含所有键的联合类型。这是设计上的考虑,不会改变。jCe28资讯网——每日最新资讯28at.com

function printUser(user: User) {  Object.keys(user).forEach((key) => {    // 不起作用!    console.log(user[key]);    // 报错:属性“key”在类型“User”上不存在。  });}

在适当的位置进行keyof typeof类型转换可以解决这个问题:jCe28资讯网——每日最新资讯28at.com

const user = {  name: "Daniel",  age: 26,};const keys = Object.keys(user);keys.forEach((key) => {  // 不再报错!  console.log(user[key as keyof typeof user]);});

通过自定义类型断言,可以在行内缩小类型:jCe28资讯网——每日最新资讯28at.com

function isKey<T extends object>(  x: T,  k: PropertyKey): k is keyof T {  return k in x;}keys.forEach((key) => {  if (isKey(user, key)) {    console.log(user[key]);    // key现在被缩小为 "name" | "age"  }});

Object.keys

问题在于使用Object.keys似乎无法按照期望的方式工作。这是因为它不会返回你需要的类型。jCe28资讯网——每日最新资讯28at.com

const user = {  name: "Daniel",  age: 26,};const keys = Object.keys(user);// keys的类型是 string[]

这意味着你不能使用键来访问对象上的值:jCe28资讯网——每日最新资讯28at.com

const nameKey = keys[0];user[nameKey];// 报错:属性“nameKey”在类型“{ name: string; age: number; }”上不存在。

TypeScript之所以返回字符串数组,是因为它的对象类型是开放的。在许多情况下,TS无法保证由Object.keys返回的键实际上存在于对象上 - 因此将它们扩展为字符串是唯一合理的解决方案。jCe28资讯网——每日最新资讯28at.com

for...in

如果尝试使用for...in循环,同样会失败,原因是键被推断为字符串,就像Object.keys一样。jCe28资讯网——每日最新资讯28at.com

function printUser(user: User) {  for (const key in user) {    console.log(user[key]);    // 报错:属性“key”在类型“User”上不存在。  }}

但在许多情况下,你可能确信自己完全了解对象的形状。jCe28资讯网——每日最新资讯28at.com

那么,怎么办呢?jCe28资讯网——每日最新资讯28at.com

解决方案1:转换为keyof typeof

第一种选择是使用keyof typeof将键转换为更具体的类型。jCe28资讯网——每日最新资讯28at.com

const user = {  name: "Daniel",  age: 26,};const keys = Object.keys(user) as Array<keyof typeof user>;keys.forEach((key) => {  // 不再报错!  console.log(user[key]);});

在索引对象时也可以进行转换。jCe28资讯网——每日最新资讯28at.com

const keys = Object.keys(user);keys.forEach((key) => {  console.log(user[key as keyof typeof user]);});

然而,as在任何形式中通常是不安全的,这也不例外。jCe28资讯网——每日最新资讯28at.com

const user = {  name: "Daniel",  age: 26,};const nonExistentKey = "id" as keyof typeof user;// 没有错误!const value = user[nonExistentKey];// as是一个强大的工具,它允许我们在类型上欺骗TypeScript

解决方案2:类型断言

通过使用isKey助手,可以在索引之前检查键是否实际存在于对象中。jCe28资讯网——每日最新资讯28at.com

function isKey<T extends object>(  x: T,  k: PropertyKey): k is keyof T {  return k in x;}keys.forEach((key) => {  if (isKey(user, key)) {    console.log(user[key]);    // key现在被缩小为 "name" | "age"  }});

解决方案3:泛型函数

再来看一个略微奇怪的解决方案。在泛型函数内部,使用in运算符将类型缩小到键。jCe28资讯网——每日最新资讯28at.com

function printEachKey<T extends object>(obj: T) {  for (const key in obj) {    console.log(obj[key]);    // key的类型被缩小为Extract<keyof T, string>  }}// 每个键都被打印出来!printEachKey({  name: "Daniel",  age: 26,});

解决方案4:将Object.keys包装在函数中

另一种解决方案是将Object.keys包装在一个返回转换类型的函数中。jCe28资讯网——每日最新资讯28at.com

const objectKeys = <T extends object>(obj: T) => {  return Object.keys(obj) as Array<keyof T>;};const keys = objectKeys({  name: "Daniel",  age: 26,});console.log(keys);// keys的类型是("name" | "age")[]

这可能是最容易被滥用的解决方案 - 将转换隐藏在函数中使其更有吸引力,可能导致人们在不考虑的情况下使用它。jCe28资讯网——每日最新资讯28at.com

结论

本文介绍了一些解决方案,从简单的类型转换到更智能的类型谓词,帮助我们更安全、更可靠地进行对象键的遍历。选择哪种方法取决于项目的需求和个人偏好,但总体而言,通过了解这些技术,我们可以更好地利用TypeScript的类型系统,提高代码的可维护性和安全性。jCe28资讯网——每日最新资讯28at.com


jCe28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-34902-0.htmlTypeScript中遍历对象键的方法

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 分享一个 Python 处理音频的库

下一篇: 在Python中什么场景下应该使用多进程和多线程?

标签:
  • 热门焦点
  • 轿车从天而降电动车主被撞身亡 超速抢道所致:现场视频让网友吵翻

    近日,上海青浦区法院判决轿车从天而降电动车主被撞身亡案,轿车车主被判有期徒刑一年。案件显示当时男子驾驶轿车在上海某路段行驶,前车忽然转弯提速超车,
  • 服务存储设计模式:Cache-Aside模式

    Cache-Aside模式一种常用的缓存方式,通常是把数据从主存储加载到KV缓存中,加速后续的访问。在存在重复度的场景,Cache-Aside可以提升服务性能,降低底层存储的压力,缺点是缓存和底
  • 分享六款相见恨晚的PPT模版网站, 祝你做出精美的PPT!

    1、OfficePLUSOfficePLUS网站旨在为全球Office用户提供丰富的高品质原创PPT模板、实用文档、数据图表及个性化定制服务。优点:OfficePLUS是微软官方网站,囊括PPT模板、Word模
  • 三万字盘点 Spring 九大核心基础功能

    大家好,我是三友~~今天来跟大家聊一聊Spring的9大核心基础功能。话不多说,先上目录:图片友情提示,本文过长,建议收藏,嘿嘿嘿!一、资源管理资源管理是Spring的一个核心的基础功能,不
  • 只需五步,使用start.spring.io快速入门Spring编程

    步骤1打开https://start.spring.io/,按照屏幕截图中的内容创建项目,添加 Spring Web 依赖项,并单击“生成”按钮下载 .zip 文件,为下一步做准备。请在进入步骤2之前进行解压。图
  • 一个注解实现接口幂等,这样才优雅!

    场景码猿慢病云管理系统中其实高并发的场景不是很多,没有必要每个接口都去考虑并发高的场景,比如添加住院患者的这个接口,具体的业务代码就不贴了,业务伪代码如下:图片上述代码有
  • 零售大模型“干中学”,攀爬数字化珠峰

    文/侯煜编辑/cc来源/华尔街科技眼对于绝大多数登山爱好者而言,攀爬珠穆朗玛峰可谓终极目标。攀登珠峰的商业路线有两条,一是尼泊尔境内的南坡路线,一是中国境内的北坡路线。相
  • 2天涨粉255万,又一赛道在抖音爆火

    来源:运营研究社作者 | 张知白编辑 | 杨佩汶设计 | 晏谈梦洁这个暑期,旅游赛道彻底火了:有的「地方」火了&mdash;&mdash;贵州村超旅游收入 1 个月超过 12 亿;有的「博主」火了&m
  • 英特尔Xe HPG游戏显卡:拥有512EU,单风扇版本

    据10 月 30 日外媒 TheVerge 消息报道,英特尔 Xe HPG Arc Alchemist 的正面实被曝光,不仅拥有 512 EU 版显卡,还拥有 128EU 的单风扇版本。另外,这款显卡 PCB
Top