在 TypeScript 中使用巢狀屬性擴充套件介面

David Mbochi Njonge 2023年1月30日
  1. 使用 TypeScript Intersection 擴充套件具有巢狀屬性的介面
  2. 使用單獨的介面結構擴充套件具有巢狀屬性的介面
  3. 通過使產品介面通用化來擴充套件具有巢狀屬性的介面
在 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 介面,它新增了屬性 productNameproductPrice。如果我們想在基礎結構中新增一個新屬性而不修改它,我們必須建立一個包含新屬性的新介面並擴充套件基礎結構。

在同一資料夾下建立一個名為 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 繼承 productNameproductPriceNewProduct 介面還實現了由新結構和繼承結構中的屬性組成的 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 繼承自基礎結構 ProductAddressStructureNewProduct 介面還包含屬性 houseNumberstreetName

使用我們用於執行第一步的步驟來執行此示例。

輸出:

Nike - Air Max
500
{ zipCode: '1233', houseNumber: 1233, streetName: 'brooklyn street' }
David Mbochi Njonge avatar David Mbochi Njonge avatar

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

相關文章 - TypeScript Interface