LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

typescript結(jié)構(gòu)化類型應(yīng)用兩例

freeflydom
2025年7月7日 8:28 本文熱度 350

第一個(gè)例子

下面的代碼定義了一個(gè)Person類型

interface Person {
  name: string;
  age: number;
}

然后又定義了一個(gè)函數(shù)打印這個(gè)類型的對(duì)象

function printPerson(person: Person) {
  console.log(`Name: ${person.name}, Age: ${person.age}`);
}

按道理來說,要調(diào)用這個(gè)函數(shù),必須傳遞一個(gè)Person類型的對(duì)象,但是你會(huì)發(fā)現(xiàn),直接傳一個(gè)對(duì)象進(jìn)去也行。

printPerson({ name: "Alice", age: 30 });

這段代碼沒有報(bào)錯(cuò),為什么呢?因?yàn)閠ypescript的結(jié)構(gòu)化類型系統(tǒng)認(rèn)為,只要傳入的對(duì)象包含了Person類型所需的所有屬性,就可以被認(rèn)為是Person類型。你甚至可以多加一些屬性,比如:

printPerson({ name: "Alice", age: 30, location: "Wonderland" });

代碼一樣可以正常運(yùn)行!

為什么?因?yàn)樵趖ypescript中,類型是基于結(jié)構(gòu)的,而不是基于名稱的。只要對(duì)象的結(jié)構(gòu)符合要求,就可以被認(rèn)為是該類型。如果一個(gè)類型A包含了類型B的所有屬性,那么類型A就可以被認(rèn)為是類型B。在使用類型B的地方,就可以使用類型A代替。

第二個(gè)例子

還是以上面的Person類型為例,假設(shè)我們要打印Person對(duì)象中的所有屬性,有的同學(xué)可能不假思索的寫下如下代碼:

interface Person {
  name: string;
  age: number;
}
const person: Person = { name: "Alice", age: 30 };
function printProperties(person: Person) {
  for (const property in person) {
    console.log(`${property}: ${person[property]}`);
  }
}
printProperties(person);

但是這段代碼卻報(bào)錯(cuò)了:

TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Person'. No index signature with a parameter of type 'string' was found on type 'Person'.

當(dāng)我第一次看到這個(gè)錯(cuò)誤時(shí),我只想撞墻,我哪里用any了,這不是胡扯嗎?但這不是對(duì)待錯(cuò)誤的正確態(tài)度,這種錯(cuò)誤如果不徹底解決,那么它就會(huì)一直困擾你,只有將它徹底擊敗,下次再遇到時(shí)才能得心應(yīng)手!

仔細(xì)看一下這個(gè)報(bào)錯(cuò),它大概描述了兩件事情:

  1. string類型的值不能用來索引Person類型。
  2. Person類型沒有定義索引簽名。

其實(shí)這兩件事本質(zhì)上說的是一個(gè)問題,那就是在TypeScript中,只有在類型中顯式定義了索引簽名,才能使用string類型的值來索引該類型。那么我們就給Person類型添加一個(gè)索引簽名:

方式一:為Person類型添加索引簽名

interface Person {
  name: string;
  age: number;
  [key: string]: any; // 索引簽名
}

[key: string]: any; 這行代碼的意思是,Person類型可以有任意數(shù)量的屬性,屬性名必須是字符串類型 ([key: string]),屬性值可以是任意類型(any)。

現(xiàn)在我們?cè)賮磉\(yùn)行printProperties函數(shù),就不會(huì)報(bào)錯(cuò)了。

方式二:使用keyof關(guān)鍵字

坦白的說,為了一個(gè)遍歷函數(shù)給Person類型添加一個(gè)索引簽名有點(diǎn)過于冗余了,其實(shí)我們可以使用另一個(gè)方法來解決這個(gè)問題,那就是使用keyof關(guān)鍵字來獲取Person類型的所有屬性名。

function printProperties(person: Person) {
  for (const property in person) {
    console.log(`${property}: ${person[property as keyof typeof person]}`);
  }
}

來看這一句代碼property as keyof typeof person, 它的執(zhí)行步驟是這樣的:

  1. 先執(zhí)行typeof person,得到Person類型。
  2. 再執(zhí)行keyof Person,得到Person類型的所有屬性名的聯(lián)合類型 - name | age
  3. 最后使用as操作符將property轉(zhuǎn)換為這個(gè)聯(lián)合類型。

這樣做的好處是,property的類型被限制為Person類型的屬性名,在本例中就是nameage這兩個(gè)屬性,絕不會(huì)超出這個(gè)范圍,這樣就可以安全地索引person對(duì)象了。

眼力好的同學(xué)可能已經(jīng)發(fā)現(xiàn)了,上面這個(gè)寫法可以簡(jiǎn)化一下,property as keyof typeof person可以簡(jiǎn)化為property as keyof Person,因?yàn)?code style="font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace, sans-serif; padding: 0px 5px; line-height: 1.8; margin: 0px 3px; display: inline-block; overflow-x: auto; vertical-align: middle; border-radius: 3px; background-color: rgb(251, 229, 225); color: rgb(192, 52, 29); border: none !important;">person的類型就是Person,所以我們可以直接使用Person類型來代替。這樣可以節(jié)省一個(gè)typeof操作符的使用。

方式三:使用Object.entries

當(dāng)然,我們還可以使用Object.entries方法來遍歷對(duì)象的屬性,這樣就不需要擔(dān)心索引簽名的問題了。

function printProperty(person: Person) {
  Object.entries(person).forEach(([key, value]) => {
    console.log(`${key}: ${value}`);
  });
}

分析一下這段代碼:

  1. Object.entries方法會(huì)返回一個(gè)二維數(shù)組,其中每個(gè)元素又是一個(gè)數(shù)組,這個(gè)數(shù)組包含了對(duì)象的屬性名和屬性值。以上面的person對(duì)象為例,Object.entries(person)會(huì)返回[['name', 'Alice'], ['age', 30]]
  2. 接下來的forEach方法會(huì)遍歷這個(gè)數(shù)組,這里使用了一個(gè)數(shù)組解構(gòu)操作符([key, value]),將每個(gè)屬性的名字賦值給key,屬性的值賦值給value,
  3. 最后使用console.log打印出來。

?轉(zhuǎn)自https://www.cnblogs.com/graphics/p/18968833


該文章在 2025/7/7 8:28:05 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
在线看片免费人成福利 | 亚洲色香蕉一区二区三区 | 亚洲日韩欧美精品国产 | 曰本高清色影视频日本高 | 亚洲精品一级精品在线高清 | 亚洲色欧影院在线观看 |