在 TypeScript 中使用巢狀屬性擴充套件介面
當我們開發應用程式時,我們可能會得到一個使用現有結構但新增新屬性的新需求。修改現有結構可能會影響我們應用程式的其他模組,建立新結構可能會導致程式碼冗餘。
在本教程中,你將學習可用於將新屬性新增到基礎結構的不同方法,而無需對其進行修改以適應你的新要求。
要成功執行本示例中提供的示例,請確保你已在計算機上安裝了 TypeScript 和節點包管理器 (npm)。
使用 TypeScript Intersection 擴充套件具有巢狀屬性的介面
在集合論中,交集是通過獲取兩個集合中共有的元素而形成的一組元素。TypeScript 中的交集以相同的方式工作,通過返回由相交結構的公共屬性構成的新結構。
要演示此示例,請開啟 Visual Studio Code 編輯器並建立一個 using-intersection
資料夾。
在此資料夾中,建立一個名為 Product.ts
的檔案。將以下程式碼複製並貼上到檔案中。
export interface Product{
productName: string
productPrice: number
productAddress:{
houseNumber: number,
streetName: string
}
}
Product.ts
檔案包含一個名為 Product
的介面,在該介面內,我們定義了一個名為 productAddress
的結構。在下一步中,我們將在不修改上述程式碼的情況下向結構體新增一個新屬性。
在同一資料夾中,建立一個名為 NewProduct.ts
的檔案。將以下程式碼複製並貼上到檔案中。
import { Product } from "./Product";
export type NewProduct = Product &{
productAddress:{
zipCode: string
}
}
let productInfo: NewProduct = {
productName: "Nike - Air Max",
productPrice: 500,
productAddress:{
houseNumber: 1233,
streetName: "brooklyn street",
zipCode: "1233"
}
}
console.log(productInfo.productName)
console.log(productInfo.productPrice)
console.log(productInfo.productAddress)
NewProduct.ts
檔案使用 type
關鍵字定義了一個名為 NewProduct
的新介面型別。NewProduct
型別使用&
符號與 Product
介面相交,並將一個名為 zipCode
的新屬性新增到基本結構 productAddress
。
productInfo
物件包含 NewProduct
的一個例項。請注意,新結構具有基礎結構中的所有屬性和相交結構的屬性。
轉到你的終端並 cd
到資料夾的位置以執行此程式碼。使用以下命令為我們的配置生成一個 tsconfig.json
檔案。
david@david-HP-ProBook-6470b:~/Documents/using-intersection$ tsc --init
確保在包上生成的 tsconfig.json
檔案中具有以下配置屬性。
{
"compilerOptions":{
"target": "es5"
"noEmitOnError":true,
}
}
使用以下命令將所有 TypeScript 檔案轉換為 Java 檔案。
david@david-HP-ProBook-6470b:~/Documents/using-intersection$ tsc
使用以下命令執行上面的示例。
david@david-HP-ProBook-6470b:~/Documents/using-intersection$ node NewProduct.js
輸出:
Nike - Air Max
500
{ houseNumber: 1233, streetName: 'brooklyn street', zipCode: '1233' }
使用單獨的介面結構擴充套件具有巢狀屬性的介面
使用其屬性建立新介面並擴充套件基本介面是在不修改基本結構的情況下向基本結構新增屬性的第二種方法。
建立一個名為 separate-interface
的資料夾,並在該資料夾內建立一個名為 ProductAddressStructure.ts
的檔案。將以下程式碼複製並貼上到檔案中。
export interface ProductAddressStructure{
houseNumber: number
streetName: string
}
上面的程式碼定義了我們想要在不修改的情況下新增屬性的基礎結構。在同一資料夾下建立一個名為 Product.ts
的檔案。將以下程式碼複製並貼上到檔案中。
import { ProductAddressStructure } from "./ProductAddressStructure"
export interface Product{
productName: string
productPrice: number
productAddress: ProductAddressStructure
}
上面的程式碼定義了一個 Product
介面,它新增了屬性 productName
和 productPrice
。如果我們想在基礎結構中新增一個新屬性而不修改它,我們必須建立一個包含新屬性的新介面並擴充套件基礎結構。
在同一資料夾下建立一個名為 NewProductAddressStructure.ts
的檔案。將以下程式碼複製並貼上到檔案中。
import { ProductAddressStructure } from "./ProductAddressStructure";
export interface NewProductAddressStructure extends ProductAddressStructure{
zipCode: string
}
上面的程式碼建立了一個包含屬性 zipCode
的新介面,並從基礎結構 ProductAddressStructure
繼承了所有屬性。
在同一資料夾中建立一個名為 NewProduct.ts
的檔案。將以下程式碼複製並貼上到檔案中。
import { NewProductAddressStructure } from "./NewProductAddressStructure";
import { Product } from "./Product";
export interface NewProduct extends Product{
productAddress: NewProductAddressStructure
}
let productInfo: NewProduct ={
productName: "Nike - Air Max",
productPrice: 500,
productAddress: {
zipCode: "1233",
houseNumber: 345,
streetName: "brooklyn street"
}
}
console.log(productInfo.productName)
console.log(productInfo.productPrice)
console.log(productInfo.productAddress)
NewProduct.ts
檔案定義了一個名為 NewProduct
的介面,它從 ProductPrice
繼承 productName
和 productPrice
。NewProduct
介面還實現了由新結構和繼承結構中的屬性組成的 NewAddressStructureInterface
。
使用與執行第一個示例相同的步驟來執行此示例。
輸出:
Nike - Air Max
500
{ zipCode: '1233', houseNumber: 345, streetName: 'brooklyn street' }
通過使產品介面通用化來擴充套件具有巢狀屬性的介面
這種方法類似於我們上面的方法,除了 Product
介面是通用的。
建立一個名為 generic-interface
的資料夾,並建立一個名為 ProductAddressStructure.ts
的檔案。將以下程式碼複製並貼上到檔案中。
export interface ProductAddressStructure{
houseNumber: number
streetName: string
}
上面的介面建立了包含兩個屬性的基礎結構。
在同一資料夾中建立一個名為 Product.ts
的檔案。將以下程式碼複製並貼上到檔案中。
import { ProductAddressStructure } from "./ProductAddressStructure"
export interface Product<T extends ProductAddressStructure> {
productName: string
productPrice: number
productAddress: T
}
Product.ts
檔案定義了一個名為 Product
的通用介面。該介面將實現限制為僅從 ProductAddressStrcture
繼承的結構。
該介面還包含一個名為 productAddress
的欄位,該欄位將被解析為 ProductAddressStructure
例項的型別。
在同一資料夾中建立一個名為 NewProductAddressStructure.ts
的檔案。將以下程式碼複製並貼上到檔案中。
import { ProductAddressStructure } from "./ProductAddressStructure";
export interface NewProductAddressStructure extends ProductAddressStructure{
zipCode: string
}
NewProductAddressStructure.ts
定義了一個名為 NewProductAddressStructure
的新介面,它繼承了 ProductAddressStructure
介面的所有基本屬性。
在同一資料夾下建立一個名為 NewProduct.ts
的檔案。將以下程式碼複製並貼上到檔案中。
import { NewProductAddressStructure } from "./NewProductAddressStructure";
import { Product } from "./Product";
export interface NewProduct extends Product<NewProductAddressStructure>{
}
let productInfo: NewProduct = {
productName: "Nike - Air Max",
productPrice: 500,
productAddress: {
zipCode: "1233",
houseNumber: 1233,
streetName: "brooklyn street"
}
}
console.log(productInfo.productName)
console.log(productInfo.productPrice)
console.log(productInfo.productAddress)
NewProduct.ts
檔案定義了一個名為 NewProduct
的介面。NewProduct
介面繼承了 Product
的所有屬性,包括包含 NewProductAddressStructure
介面的屬性 zipCode
的通用結構 productAddress
。
由於 NewProductAddressStructure
繼承自基礎結構 ProductAddressStructure
,NewProduct
介面還包含屬性 houseNumber
和 streetName
。
使用我們用於執行第一步的步驟來執行此示例。
輸出:
Nike - Air Max
500
{ zipCode: '1233', houseNumber: 1233, streetName: 'brooklyn street' }
David is a back end developer with a major in computer science. He loves to solve problems using technology, learning new things, and making new friends. David is currently a technical writer who enjoys making hard concepts easier for other developers to understand and his work has been published on multiple sites.
LinkedIn GitHub