Using TypeScript — Object Types and Intersections
By: John Au-Yeung
Tags: Technology, Software Development, JavaScript, Programming, Web Development

Photo by Jenni Miska on Unsplash

TypeScript is a natural extension of JavaScript that’s used in many projects in place of JavaScript.

However, not everyone knows how it actually works.

In this article, we’ll look at how to work with objects in TypeScript by creating intersection types and checking object structures.

Checking Properties

This means that we can’t use the typeof operator to check the type of objects.

Instead, we must find better alternatives.

One way is to check if a property is in the object.

For instance, we can use the in operator:

arr.forEach(a => {

if ("breed" in a) {

console.log("animal");

} else {

console.log("person");

}

});

The in operator checks if the 'breed' property is in an object.

It checks both its own and inherited properties.

And it returns true if a property is found in any of those places and false otherwise.

However, this doesn’t help us if a property is in both types.

Type Predicate Function

We can also check if a property is undefined to check if an object is of a certain type.

For instance, we can write:

arr.forEach(a => {

if (typeof a.breed !== "undefined") {

console.log("animal");

} else {

console.log("person");

}

});

This is similar to in except that we used typeof to check for a property instead of using the in operator.

Type Intersections

We can use type intersections to define 2 object types that are combined together.

A variable assigned to an object type should have all the properties from both types rather than some of them like union types.

For instance, we can create an intersection type and assign it to a value by writing:

type Thing = { name: string };

type Animal = { breed: string }; const animal: Thing & Animal = {

name: "james",

breed: "dog"

};

We defined a Thing type and an Animal and combined them into an intersection type by using the & operator.

This means that animal must have properties from both Thing and Animal included.

If we skip one or more of them, then the TypeScript compiler will give us an error.

For instance, if we have:

const animal: Thing & Animal = {

name: "jame"

};

Then we’ll get ‘Type ‘{ name: string; }’ is not assignable to type ‘Thing & Animal’. Property ‘breed’ is missing in type ‘{ name: string; }’

We can use intersection types for introducing new properties to existing objects.

For instance, if we have:

type Thing = { name: string };

type Animal = { breed: string }; const thing: Thing = {

name: "james"

}; const animal: Animal = {

breed: "cat"

}; const cat: Thing & Animal = {

...thing,

...animal

};

Then TypeScript compiler won’t throw an error because it recognizes that name and breed are part of the Thing & Animal type.

As long as the property names and the corresponding data type match, the TypeScript compiler can figure out that it matches the structure of an intersection type.

Merging Properties with the Same Type

We can also merge types with overlapping properties.

For instance, if we have:

type Thing = { name: string };

type Animal = { name: string };

Then anything assigned to the Thing & Animal type variable would have the string property called name .

Photo by Brooke Lark on Unsplash

Merging Properties with Different Types

If there are properties with different types, then both properties will be merged together as an intersection.

For instance, if we have:

type Thing = { age: string };

type Animal = { age: number }; const thing: Thing = {

age: "1"

}; const animal: Animal = {

age: 1

}; const cat: Thing & Animal = {

...thing,

...animal

};

Then we would get an error from the compiler since age has type string & number which no value matches.

Therefore, we shouldn’t have properties with different types in the object types that we intersect.

Conclusion

We can create intersection types to merge object types into one type.

Then when a variable or parameter has the intersection type, it must include all the properties of both types, and the data type of the property must be an intersection of data types from both types.