在 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