在 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