如何在TypeScript中正确的遍历一个对象

目录
  • JavaScript
  • TypeScript
    • for...in
    • Object.keys
    • Object.entries
  • 思考
  • 总结

JavaScript

在讲解用 Ts 遍历一个对象之前, 我们先说说 在 Js 中怎么实现, for...in、Object.keys, 一个简单的例子:

// for...in
const obj = {
  name: 'itsuki',
  address: 'hangzhou',
};
for (const key in obj) {
  console.log(key, obj[key].toUpperCase());
}
// Object.keys
Object.keys(obj).forEach(key => {
  console.log(key, obj[key].toUpperCase());
});

// 输出
// name ITSUKI
// address HANGZHOU

TypeScript

for...in

但是在 TypeScript 中, 如果你直接这么用的话, 发现会报错.

type Person = {
  name: string;
  address: string;
};
const obj: Person = {
  name: 'itsuki',
  address: 'hangzhou',
};
function print(obj: Person) {
  for (const key in obj) {
    //
    // key:string 不能分配给 { name:string; age:number }类型
    console.log(key, obj[key].toUpperCase());
  }
}
print(obj)

我们知道for...in、Object.keys拿到的是对象的 key, 而在对象中所有的 key 都是字符串, 所以它无法分配给Person的name、address.

但是我们可以keyof来解决这个问题.

function print(obj:Person){
  let key: keyof Person;
  for (key in obj) {
    //
    console.log(key, obj[key].toUpperCase());
  }
}

Object.keys

在使用Object.keys时, 我们可以使用as运算符来解决.

function print(obj: Person) {
  Object.keys(obj).forEach((k) => {
    //
    console.log(k, obj[k as keyof Person].toUpperCase());
  });
}

我们可以把这个抽离出一个函数:

function getKeys<T>(obj: T) {
  return Object.keys(obj) as Array<keyof T>;
}
getKeys(obj); // (keyof Person)[]

Object.entries

我们也可以使用Object.entries()来遍历对象.

Object.entries(obj).forEach(([k, v]) => {
  console.log(k, v);
});

思考

以下是我自己的思考, 如有错误, 请指正

我想Object.keys()返回的是一个string[], 是因为它是在运行时确定的, 我们知道TypeScript做的只是静态类型的检查, 即使我们使用keyof Person返回了 name | address, 但是我们不能肯定在运行时它就是这两个字段.

比如说:

const obj2 = {
  name: 'itsuki',
  address: 'hangzhou',
  age: 20,
};

print(obj2)
// 编译时: , 因为它有name、address属性
// 运行时: , 因为age字段是number, 没有toUpperCase方法

然后我在 Github issue 里面找到这一句话:

TS 中的类型是开放式的。因此, keysof 可能会少于在运行时获得的所有属性。

它更要我明白了, 为什么keys()返回的是一个string[], 而不是一个(keyof Person)[].

总结

到此这篇关于如何在TypeScript中正确的遍历一个对象的文章就介绍到这了,更多相关Ts遍历对象内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • js 遍历对象的属性的代码

    如: 复制代码 代码如下: Function.prototype.addMethod=function(methodName,func){ if(!this.prototype[methodName]){ this.prototype[methodName]=func;//给原型增加方法,此方法会影响到该类型的实例上 } return this.prototype;//返回原型,此类型实例可以进行链形调用 } function CustomObject(name,value){ this.nam

  • Javascript的数组与字典用法与遍历对象的属性技巧

    Javascript 的数组Array,既是一个数组,也是一个字典(Dictionary).先举例看看数组的用法. 复制代码 代码如下: var a = new Array(); a[0] = "Acer"; a[1] = "Dell"; for (var i = 0; i < a.length; i++) { alert(a[i]); } 下面再看一下字典的用法. 复制代码 代码如下: var computer_price = new Array(); co

  • JS 5种遍历对象的方式

    几天前一个小伙伴问我 Object.getOwnPropertyNames() 是干什么用的 平时还真没有使用到这个方法,一时不知如何回答 从方法名称来分析,应该是返回的是对象自身属性名组成的数组 那和 Object.keys() 方法不就一样了吗 感觉事情并不这么简单,于是我仔细看了一下这几种遍历对象的方法的区别 for in for in 循环是最基础的遍历对象的方式,它还会得到对象原型链上的属性 // 创建一个对象并指定其原型,bar 为原型上的属性 const obj = Object.

  • js中遍历对象的属性和值的方法

    实例如下: var Statistics_Website_logo ={ 'Website_logo_title':'学而思', 'Website_logo_Theme':'教育行业', 'Website_logo_Company':'好未来' }; for (var Key in Statistics_Website_logo){ Websitelogo =Websitelogo+'&'+''+Key+'='+Statistics_Website_logo[Key]+''; } 以上这篇js中

  • TypeScript遍历对象属性的问题

    目录 一.问题 二.解决办法 1. 把对象声明as any 2. 给对象声明一个接口 3. 使用泛型 4. 使用keyof 一.问题 比如下面的代码: type Animal = { name: string; age: number } const animal:Animal={ name:"dog", age:12 } function test(obj:Animal) { for (let k in obj) { console.log(obj[k]).//这里出错 } } te

  • 如何在TypeScript中正确的遍历一个对象

    目录 JavaScript TypeScript for...in Object.keys Object.entries 思考 总结 JavaScript 在讲解用 Ts 遍历一个对象之前, 我们先说说 在 Js 中怎么实现, for...in.Object.keys, 一个简单的例子: // for...in const obj = { name: 'itsuki', address: 'hangzhou', }; for (const key in obj) { console.log(ke

  • 如何在TypeScript中处理日期字符串

    目录 前言: 一.模板字面量类型 二.类型谓词缩小范围 三.定义日期字符串 总结: 前言: 在我最近的一个项目中,我必须去处理多个自定义的日期字符串表示法,比如YYYY-MM-DD和YYYYMMDD.由于这些日期是字符串变量,TypeScript默认会推断成为string类型.虽然这在技术实现上没有错,但是在工作中使用这样的类型定义是很宽泛的,使得有效处理这些日期字符串变得很困难.例如,let dog = 'alfie'也被推断为一个string类型. 在这篇文章中,我会将我的解决方法呈现给你,

  • 如何在JavaScript中正确处理变量

    变量无处不在.即便我们写一个小函数或一个小工具,也要声明.赋值和读取变量.增强对变量的重视,可以提高代码的可读性和可维护性. 1.建议使用 const,要么使用 let 用 const 或 let 声明自己的 JavaScript 变量.两者之间的主要区别是 const 变量在声明时需要初始化,并且一旦初始化就无法再重新赋值. // const 需要初始化 const pi = 3.14; // const 不能被重新赋值 pi = 4.89; // throws "TypeError: Ass

  • TypeScript中正确使用interface和type的方法实例

    目录 前言 interface type 附:interface和type不同点 总结 前言 interface 和 type 都是用来定义类型,可以理解定义 shape ,那么 shape 表示一种设计大框,或者说只要具有某些特征或者行为就是为一类事物.在有些面向例如 Java 语言中,interface 用于定义行为,如果一个类实现了某一个 interface 表示该类具有某种行为或者说具有某种能力,例如writable 或者 readable .可以通过行为来对事物进行划分.interfa

  • 如何在php中正确的使用json

    从5.2版本开始,PHP原生提供json_encode()和json_decode()函数,前者用于编码,后者用于解码. 1.json_encode()该函数主要用来将数组和对象,转换为json格式.先看一个数组转换的例子:$arr = array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);echo json_encode($arr); 上面代码的输出结果为:{"a":1,"b":2,"c&qu

  • C#中使用反射遍历一个对象属性及值的小技巧

    总结: 对应某个类的实例化的对象tc, 遍历获取所有属性(子成员)的方法(采用反射): 复制代码 代码如下: Type t = tc.GetType();//获得该类的Type //再用Type.GetProperties获得PropertyInfo[],然后就可以用foreach 遍历了 foreach (PropertyInfo pi in t.GetProperties()) {     object value1 = pi.GetValue(tc, null));//用pi.GetVal

  • 如何在java中正确使用注释

    Java提供了3种类型的注释: 单行注释(C++风格) 在Java中最简单的注释是单行注释.它以两个正斜杠开始并到行尾结束.例如: // this is a single-line comment x = 1; // a single-line comment after code 多行注释(C风格) Java同样提供跨越多行的注释类型.这种类型的注释以紧跟着一个星号的正斜杠开始,并以紧跟着一个正斜杠的星号结束.这种类型注释的开始和结束分界符可以在同一行里也可以在不同的行上.例如: /* Thi

  • 在Typescript中如何使用for...in详解

    如何在Typescript中使用for...in ?本人在TS中用for...in出现了些问题,也想到了一些解决方法.那么先来看看下面报错的代码吧. interface ABC { a: string b: string } const x: ABC = { a:'1', b:'2' } const y: ABC = { a:'3', b:'4' } for (const key in x) { // 在类型 "ABC" 上找不到具有类型为 "string" 的参数

  • TypeScript中import type与import的区别详析

    目录 背景 import type vs import 使用 import type 的好处 参考链接 总结 背景 这周遇到了一个比较奇怪的问题:如何在 TypeScript 中根据某个 enum 的取值来执行后续逻辑? 按理来说应该很简单,这是 enum 的定义: export enum MyEnum { DEFAULT = 0, SOME_VALUE = 1, SOME_OTHER_VALUE = 2, } 然后在另一个项目中,通过 import type 来引入: import type

  • TypeScript中extends的正确打开方式详解

    目录 前言 extends第一式:继承 类继承类 接口继承接口 接口继承类 extends第二式:三元表达式条件判断 普通的三元表达式条件判断 情况一:Type1和Type2为同一种类型. 情况二:Type1是Type2的子类型. 情况三: Type2类型兼容类型Type1. 带有泛型的三元表达式条件判断 extends第三式:泛型约束 前言 最近完整地看了一遍TypeScript的官方文档,发现文档中有一些知识点没有专门讲解到,或者是讲解了但却十分难以理解,因此就有了这一系列的文章,我将对没有

随机推荐