狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

typescript結構化類型應用兩例

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

第一個例子

下面的代碼定義了一個Person類型

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

然后又定義了一個函數打印這個類型的對象

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

按道理來說,要調用這個函數,必須傳遞一個Person類型的對象,但是你會發現,直接傳一個對象進去也行。

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

這段代碼沒有報錯,為什么呢?因為typescript的結構化類型系統認為,只要傳入的對象包含了Person類型所需的所有屬性,就可以被認為是Person類型。你甚至可以多加一些屬性,比如:

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

代碼一樣可以正常運行!

為什么?因為在typescript中,類型是基于結構的,而不是基于名稱的。只要對象的結構符合要求,就可以被認為是該類型。如果一個類型A包含了類型B的所有屬性,那么類型A就可以被認為是類型B。在使用類型B的地方,就可以使用類型A代替。

第二個例子

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

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);

但是這段代碼卻報錯了:

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'.

當我第一次看到這個錯誤時,我只想撞墻,我哪里用any了,這不是胡扯嗎?但這不是對待錯誤的正確態度,這種錯誤如果不徹底解決,那么它就會一直困擾你,只有將它徹底擊敗,下次再遇到時才能得心應手!

仔細看一下這個報錯,它大概描述了兩件事情:

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

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

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

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

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

現在我們再來運行printProperties函數,就不會報錯了。

方式二:使用keyof關鍵字

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

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

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

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

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

眼力好的同學可能已經發現了,上面這個寫法可以簡化一下,property as keyof typeof person可以簡化為property as keyof Person,因為person的類型就是Person,所以我們可以直接使用Person類型來代替。這樣可以節省一個typeof操作符的使用。

方式三:使用Object.entries

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

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

分析一下這段代碼:

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

?轉自https://www.cnblogs.com/graphics/p/18968833


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