TypeScript中遍历对象键的方法

 更新时间:2023年11月28日 10:18:24   作者:黑土豆  
在日常的TypeScript开发中,经常需要遍历对象的键来执行各种操作,,在本文中,我们将深入研究这个问题,并提供几种解决方案,以便在遍历对象键时更安全、更灵活地操作,文中有详细的代码讲解,需要的朋友可以参考下

前言

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

背景

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

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

在适当的位置进行keyof typeof类型转换可以解决这个问题:

const user = {
  name: "Daniel",
  age: 26,
};

const keys = Object.keys(user);

keys.forEach((key) => {
  // 不再报错!
  console.log(user[key as keyof typeof user]);
});

通过自定义类型断言,可以在行内缩小类型:

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似乎无法按照期望的方式工作。这是因为它不会返回你需要的类型。

const user = {
  name: "Daniel",
  age: 26,
};

const keys = Object.keys(user);

// keys的类型是 string[]

这意味着你不能使用键来访问对象上的值:

const nameKey = keys[0];

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

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

For...in循环

如果尝试使用for...in循环,同样会失败,原因是键被推断为字符串,就像Object.keys一样。

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

但在许多情况下,你可能确信自己完全了解对象的形状。

那么,怎么办呢?

解决方案

解决方案1:转换为keyof typeof

第一种选择是使用keyof typeof将键转换为更具体的类型。

const user = {
  name: "Daniel",
  age: 26,
};

const keys = Object.keys(user) as Array<keyof typeof user>;

keys.forEach((key) => {
  // 不再报错!
  console.log(user[key]);
});

在索引对象时也可以进行转换。

const keys = Object.keys(user);

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

然而,as在任何形式中通常是不安全的,这也不例外。

const user = {
  name: "Daniel",
  age: 26,
};

const nonExistentKey = "id" as keyof typeof user;

// 没有错误!
const value = user[nonExistentKey];
// as是一个强大的工具,它允许我们在类型上欺骗TypeScript。

解决方案2:类型断言

通过使用isKey助手,可以在索引之前检查键是否实际存在于对象中。

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运算符将类型缩小到键。

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包装在一个返回转换类型的函数中。

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")[]

这可能是最容易被滥用的解决方案 - 将转换隐藏在函数中使其更有吸引力,可能导致人们在不考虑的情况下使用它。

结论

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

以上就是TypeScript中遍历对象键的方法的详细内容,更多关于TypeScript遍历对象键的资料请关注脚本之家其它相关文章!

相关文章

  • 原生JS实现无缝轮播图片

    原生JS实现无缝轮播图片

    这篇文章主要为大家详细介绍了原生JS实现无缝轮播图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-06-06
  • javascript设计模式 – 桥接模式原理与应用实例分析

    javascript设计模式 – 桥接模式原理与应用实例分析

    这篇文章主要介绍了javascript设计模式 – 桥接模式,结合实例形式分析了javascript桥接模式基本概念、原理、用法及操作注意事项,需要的朋友可以参考下
    2020-04-04
  • 微信小程序记住密码的功能简单几步实现

    微信小程序记住密码的功能简单几步实现

    软件中的“记住密码”选框不知道大家平时会不会勾选,反正对于一个重度懒癌患者的我来说就没有不勾选的时候,毕竟隔一段时间就重新输入一遍难记又难输的账号密码,想想就让人头皮发麻。今天教大家用代码在微信小程序中实现这个简单的小功能
    2023-01-01
  • JavaScript引用类型Date常见用法实例分析

    JavaScript引用类型Date常见用法实例分析

    这篇文章主要介绍了JavaScript引用类型Date常见用法,结合实例形式分析了引用类型Date基本创建、参数使用及相关注意事项,需要的朋友可以参考下
    2018-08-08
  • 在微信小程序中使用mqtt服务的方法

    在微信小程序中使用mqtt服务的方法

    这篇文章主要介绍了在微信小程序中使用mqtt服务的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • Javascript 去除数组的重复元素

    Javascript 去除数组的重复元素

    在js中,如何去除指定数组中的重复元素?
    2010-05-05
  • JavaScript中的回调函数实例讲解

    JavaScript中的回调函数实例讲解

    今天小编就为大家分享一篇关于JavaScript中的回调函数实例讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • 收藏一个代码

    收藏一个代码

    收藏一个代码...
    2006-08-08
  • js菜单代码js菜单特效代码

    js菜单代码js菜单特效代码

    不用div+css实现的js菜单特效代码用js+table实现 默认选中一个,点击后 选中的项目“变白”。不用css+div 高手给做一下 多谢了 演示站:www.allss.com.cn 演示站使用css+div的 改成js+table的
    2008-01-01
  • js实现上传图片预览方法

    js实现上传图片预览方法

    这篇文章主要为大家详细介绍了js实现上传照片预览的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10

最新评论