How to Extend an Interface With Nested Properties in TypeScript
- Extend an Interface With Nested Properties Using TypeScript Intersection
- Extend an Interface With Nested Properties Using a Separate Interface Structure
- Extend an Interface With Nested Properties by Making the Product Interface Generic
When we are developing applications, we may get a new requirement that uses the existing structure but with the addition of new properties. Modifying the existing structure might affect other modules of our application, and creating a new structure might lead to redundancy in our code.
In this tutorial, you will learn the different methods that you can use to add new properties to your base structure without modifying it to accommodate your new requirement.
To successfully execute the examples provided in this example, ensure that you have installed TypeScript and Node Package Manager (npm) on your machine.
Extend an Interface With Nested Properties Using TypeScript Intersection
In Set theory, an intersection is a set of elements formed by getting the elements that are common in two sets. An intersection in TypeScript works the same way by returning a new structure made from the common properties of the intersected structures.
To demonstrate this example, open Visual Studio Code editor and create a using-intersection
folder.
Inside this folder, create a file named Product.ts
. Copy and paste the following code into the file.
export interface Product{
productName: string
productPrice: number
productAddress:{
houseNumber: number,
streetName: string
}
}
The Product.ts
file contains an interface named Product
, and inside this interface, we have defined a structure named productAddress
. In the next step, we will add a new property to the structure without modifying the above code.
In the same folder, create a file named NewProduct.ts
. Copy and paste the following code into the file.
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)
The NewProduct.ts
file defines a new interface type named NewProduct
using the type
keyword. The NewProduct
type is intersected with the Product
interface using the &
symbol and adds a new property named zipCode
to the base structure productAddress
.
The productInfo
object contains an instance of NewProduct
. Note that the new structure has all the properties in the base structure and the property of the intersected structure.
Go to your terminal and cd
to the folder’s location to run this code. Use the following command to generate a tsconfig.json
file for our configuration.
david@david-HP-ProBook-6470b:~/Documents/using-intersection$ tsc --init
Ensure you have the following configuration properties in the tsconfig.json
file generated on your package.
{
"compilerOptions":{
"target": "es5"
"noEmitOnError":true,
}
}
Use the following command to transpile all your TypeScript files to Java files.
david@david-HP-ProBook-6470b:~/Documents/using-intersection$ tsc
Use the following command to run the example above.
david@david-HP-ProBook-6470b:~/Documents/using-intersection$ node NewProduct.js
Output:
Nike - Air Max
500
{ houseNumber: 1233, streetName: 'brooklyn street', zipCode: '1233' }
Extend an Interface With Nested Properties Using a Separate Interface Structure
Creating a new interface with its properties and extending the base interface is the second way to add properties to the base structure without modifying it.
Create a folder named separate-interface
, and create a file named ProductAddressStructure.ts
inside the folder. Copy and paste the following code into the file.
export interface ProductAddressStructure{
houseNumber: number
streetName: string
}
The code above defines our base structure that we want to add properties without modifying. Create a file named Product.ts
under the same folder. Copy and paste the following code into the file.
import { ProductAddressStructure } from "./ProductAddressStructure"
export interface Product{
productName: string
productPrice: number
productAddress: ProductAddressStructure
}
The code above defines a Product
interface that adds the properties productName
and productPrice
. If we want to add a new property to the base structure without modifying it, we have to create a new interface containing the new property and extend the base structure.
Create a file named NewProductAddressStructure.ts
under the same folder. Copy and paste the following code into the file.
import { ProductAddressStructure } from "./ProductAddressStructure";
export interface NewProductAddressStructure extends ProductAddressStructure{
zipCode: string
}
The above code creates a new interface containing the property zipCode
and inherits all the properties from the base structure ProductAddressStructure
.
Create a file named NewProduct.ts
inside the same folder. Copy and paste the following code into the file.
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)
The NewProduct.ts
file defines an interface named NewProduct
that inherits the productName
and productPrice
from the ProductPrice
. The NewProduct
interface also implements the NewAddressStructureInterface
composed of the properties in the new structure and the inherited structure.
Use the same steps we used to execute the first example to run this example.
Output:
Nike - Air Max
500
{ zipCode: '1233', houseNumber: 345, streetName: 'brooklyn street' }
Extend an Interface With Nested Properties by Making the Product Interface Generic
This approach is similar to the one we have above, except that the Product
interface is generic.
Create a folder named generic-interface
, and create a file named ProductAddressStructure.ts
. Copy and paste the following code into the file.
export interface ProductAddressStructure{
houseNumber: number
streetName: string
}
The above interface creates the base structure containing two properties.
Create a file named Product.ts
inside the same folder. Copy and paste the following code into the file.
import { ProductAddressStructure } from "./ProductAddressStructure"
export interface Product<T extends ProductAddressStructure> {
productName: string
productPrice: number
productAddress: T
}
The Product.ts
file defines a generic interface named Product
. The interface will restrict the implementation to structures that only inherit from the ProductAddressStrcture
.
The interface also contains a field named productAddress
that will be resolved to a type of the ProductAddressStructure
instance.
Create a file named NewProductAddressStructure.ts
in the same folder. Copy and paste the following code to the file.
import { ProductAddressStructure } from "./ProductAddressStructure";
export interface NewProductAddressStructure extends ProductAddressStructure{
zipCode: string
}
The NewProductAddressStructure.ts
defines a new interface named NewProductAddressStructure
that inherits all the base properties of the ProductAddressStructure
interface.
Create a file named NewProduct.ts
under the same folder. Copy and paste the following code into the file.
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)
The NewProduct.ts
file defines an interface named NewProduct
. The NewProduct
interface inherits all the properties from the Product
, including the generic structure productAddress
that contains the property zipCode
from the NewProductAddressStructure
interface.
Since the NewProductAddressStructure
inherits from the base structure ProductAddressStructure
, the NewProduct
interface also contains the properties houseNumber
and streetName
.
Use the steps we used to execute the first step to run this example.
Output:
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