自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

TypeScript中遍歷對象鍵的方法

開發(fā) 前端
本文介紹了一些解決方案,從簡單的類型轉(zhuǎn)換到更智能的類型謂詞,幫助我們更安全、更可靠地進行對象鍵的遍歷。選擇哪種方法取決于項目的需求和個人偏好,但總體而言,通過了解這些技術(shù),我們可以更好地利用TypeScript的類型系統(tǒng),提高代碼的可維護性和安全性。

前言

在日常的TypeScript開發(fā)中,經(jīng)常需要遍歷對象的鍵來執(zhí)行各種操作。然而,使用Object.keys時可能會遇到一些類型相關(guān)的困擾,因為它返回的是一個字符串數(shù)組,而不是期望的鍵的聯(lián)合類型。這可能導致在代碼中引入一些不安全的類型轉(zhuǎn)換。在本文中,我們將深入研究這個問題,并提供幾種解決方案,以便在遍歷對象鍵時更安全、更靈活地操作。

背景

使用Object.keys進行遍歷并不能按照預期工作。這是因為Object.keys返回一個字符串數(shù)組,而不是包含所有鍵的聯(lián)合類型。這是設(shè)計上的考慮,不會改變。

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

在適當?shù)奈恢眠M行keyof typeof類型轉(zhuǎn)換可以解決這個問題:

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


const keys = Object.keys(user);


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

通過自定義類型斷言,可以在行內(nèi)縮小類型:

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現(xiàn)在被縮小為 "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之所以返回字符串數(shù)組,是因為它的對象類型是開放的。在許多情況下,TS無法保證由Object.keys返回的鍵實際上存在于對象上 - 因此將它們擴展為字符串是唯一合理的解決方案。

for...in

如果嘗試使用for...in循環(huán),同樣會失敗,原因是鍵被推斷為字符串,就像Object.keys一樣。

function printUser(user: User) {
  for (const key in user) {
    console.log(user[key]);
    // 報錯:屬性“key”在類型“User”上不存在。
  }
}

但在許多情況下,你可能確信自己完全了解對象的形狀。

那么,怎么辦呢?

解決方案1:轉(zhuǎn)換為keyof typeof

第一種選擇是使用keyof typeof將鍵轉(zhuǎn)換為更具體的類型。

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


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


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

在索引對象時也可以進行轉(zhuǎn)換。

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現(xiàn)在被縮小為 "name" | "age"
  }
});

解決方案3:泛型函數(shù)

再來看一個略微奇怪的解決方案。在泛型函數(shù)內(nèi)部,使用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包裝在函數(shù)中

另一種解決方案是將Object.keys包裝在一個返回轉(zhuǎn)換類型的函數(shù)中。

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

這可能是最容易被濫用的解決方案 - 將轉(zhuǎn)換隱藏在函數(shù)中使其更有吸引力,可能導致人們在不考慮的情況下使用它。

結(jié)論

本文介紹了一些解決方案,從簡單的類型轉(zhuǎn)換到更智能的類型謂詞,幫助我們更安全、更可靠地進行對象鍵的遍歷。選擇哪種方法取決于項目的需求和個人偏好,但總體而言,通過了解這些技術(shù),我們可以更好地利用TypeScript的類型系統(tǒng),提高代碼的可維護性和安全性。


責任編輯:武曉燕 來源: 黑土豆的前端博客
相關(guān)推薦

2021-05-19 07:02:42

JS對象方法

2010-11-11 10:53:22

SQL Server遍

2021-07-27 06:06:34

TypeScript語言運算符

2023-09-04 19:15:19

itemPython版本

2021-07-22 07:20:24

JS 遍歷方法前端

2018-12-19 19:30:46

JavaScript創(chuàng)建對象前端

2017-03-20 14:45:42

JavaScript詳解

2023-11-21 15:23:15

JavaScript工具

2011-07-21 17:19:47

java面向?qū)ο?/a>

2020-09-23 09:08:05

typescript

2022-04-11 08:42:09

TypeScript子類型定義

2024-05-11 10:19:31

TypeScript類型接口

2022-08-08 09:00:42

TypeScript映射類型

2010-10-09 10:04:48

MySQL定義外鍵

2010-11-22 09:43:07

MySQL定義外鍵

2010-09-09 13:32:14

SQL函數(shù)遍歷

2012-06-27 09:44:28

ibmdw

2024-02-21 08:33:27

GoReadDir性能

2022-05-19 09:01:08

TypeScript元組對象

2009-06-30 09:37:02

對象比較Java
點贊
收藏

51CTO技術(shù)棧公眾號