如何在TypeScript中正確的遍歷一個(gè)對(duì)象
JavaScript
在講解用 Ts 遍歷一個(gè)對(duì)象之前, 我們先說(shuō)說(shuō) 在 Js 中怎么實(shí)現(xiàn), for...in、Object.keys, 一個(gè)簡(jiǎn)單的例子:
// 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 中, 如果你直接這么用的話(huà), 發(fā)現(xiàn)會(huì)報(bào)錯(cuò).
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 }類(lèi)型 console.log(key, obj[key].toUpperCase()); } } print(obj)
我們知道for...in、Object.keys拿到的是對(duì)象的 key, 而在對(duì)象中所有的 key 都是字符串, 所以它無(wú)法分配給Person的name、address.
但是我們可以keyof來(lái)解決這個(gè)問(wèn)題.
function print(obj:Person){ let key: keyof Person; for (key in obj) { // ? console.log(key, obj[key].toUpperCase()); } }
Object.keys
在使用Object.keys時(shí), 我們可以使用as運(yùn)算符來(lái)解決.
function print(obj: Person) { Object.keys(obj).forEach((k) => { // ? console.log(k, obj[k as keyof Person].toUpperCase()); }); }
我們可以把這個(gè)抽離出一個(gè)函數(shù):
function getKeys<T>(obj: T) { return Object.keys(obj) as Array<keyof T>; } getKeys(obj); // (keyof Person)[]
Object.entries
我們也可以使用Object.entries()來(lái)遍歷對(duì)象.
Object.entries(obj).forEach(([k, v]) => { console.log(k, v); });
思考
以下是我自己的思考, 如有錯(cuò)誤, 請(qǐng)指正
我想Object.keys()返回的是一個(gè)string[], 是因?yàn)樗窃谶\(yùn)行時(shí)確定的, 我們知道TypeScript做的只是靜態(tài)類(lèi)型的檢查, 即使我們使用keyof Person返回了 name | address, 但是我們不能肯定在運(yùn)行時(shí)它就是這兩個(gè)字段.
比如說(shuō):
const obj2 = { name: 'itsuki', address: 'hangzhou', age: 20, }; print(obj2) // 編譯時(shí): ?, 因?yàn)樗衝ame、address屬性 // 運(yùn)行時(shí): ?, 因?yàn)閍ge字段是number, 沒(méi)有toUpperCase方法
然后我在 Github issue 里面找到這一句話(huà):
TS 中的類(lèi)型是開(kāi)放式的。因此, keysof 可能會(huì)少于在運(yùn)行時(shí)獲得的所有屬性。
它更要我明白了, 為什么keys()返回的是一個(gè)string[], 而不是一個(gè)(keyof Person)[].
總結(jié)
到此這篇關(guān)于如何在TypeScript中正確的遍歷一個(gè)對(duì)象的文章就介紹到這了,更多相關(guān)Ts遍歷對(duì)象內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Typescript tipe freshness 更嚴(yán)格對(duì)象字面量檢查
- TypeScript數(shù)組實(shí)現(xiàn)棧與對(duì)象實(shí)現(xiàn)棧的區(qū)別詳解
- 淺談typescript中keyof與typeof操作符用法
- 基于Vue3+TypeScript的全局對(duì)象的注入和使用詳解
- JS?TypeScript的Map對(duì)象及聯(lián)合類(lèi)型實(shí)戰(zhàn)
- TypeScript對(duì)象解構(gòu)操作符在Spartacus實(shí)際項(xiàng)目開(kāi)發(fā)中的應(yīng)用解析
相關(guān)文章
配置eslint規(guī)范項(xiàng)目代碼風(fēng)格
這篇文章主要介紹了配置eslint規(guī)范項(xiàng)目代碼風(fēng)格,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-03-03LayUi中接口傳數(shù)據(jù)成功,表格不顯示數(shù)據(jù)的解決方法
今天小編就為大家分享一篇LayUi中接口傳數(shù)據(jù)成功,表格不顯示數(shù)據(jù)的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08在js中判斷checkboxlist(.net控件客戶(hù)端id)是否有選中
添加或修改內(nèi)容時(shí),需要對(duì)關(guān)鍵數(shù)據(jù)進(jìn)行判空處理,checkboxlist是否有選擇項(xiàng)如何使用js判斷實(shí)現(xiàn),接下來(lái)為大家詳細(xì)介紹下實(shí)現(xiàn)方法,感興趣的朋友可以參考下哈2013-04-04微信小程序wx.request實(shí)現(xiàn)后臺(tái)數(shù)據(jù)交互功能分析
這篇文章主要介紹了微信小程序wx.request實(shí)現(xiàn)后臺(tái)數(shù)據(jù)交互功能,分析微信小程序wx.request在后臺(tái)數(shù)據(jù)交互過(guò)程中遇到的問(wèn)題與相關(guān)的解決方法,需要的朋友可以參考下2017-11-11js實(shí)現(xiàn)瀏覽器倒計(jì)時(shí)跳轉(zhuǎn)頁(yè)面效果
這篇文章主要為大家詳細(xì)介紹了js瀏覽器倒計(jì)時(shí)跳轉(zhuǎn)頁(yè)面效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08基于VSCode調(diào)試網(wǎng)頁(yè)JavaScript代碼過(guò)程詳解
這篇文章主要介紹了基于VSCode調(diào)試網(wǎng)頁(yè)JavaScript代碼過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07javascript檢查表單數(shù)據(jù)是否改變的方法
需要檢查用戶(hù)是否修改了一個(gè)表單中的內(nèi)容,可以使用本文提供的方法,如果修改了表單的內(nèi)容則返回true,沒(méi)修改則返回false,有需求的朋友可以參考下2013-07-07javascript利用初始化數(shù)據(jù)裝配模版的實(shí)現(xiàn)代碼
實(shí)現(xiàn)一個(gè)通用方法,使用初始化數(shù)據(jù)來(lái)裝配模版。需要的朋友可以參考下。2010-11-11