Skip to main content

InstanceType<Type> Utility Types in TypeScript With Examples

What Is InstanceType<Type>

InstanceType<Type> is a utility type in TypeScript that helps you get the instance type of a class or constructor function. Basically, it extracts the type of the object that would be created if you were to use the new keyword with the given class or constructor function. This is useful when you want to work with instances of a specific class, without having to create an instance first or explicitly define the instance type.

Syntax

Here is the basic syntax for ussing the InstanceType<Type> utility type

type NewType = InstanceType<Type>;

The above syntax is used to create a new type alias called NewType, which represents the instance type of a given class or constructor function (Type). Here's a breakdown of the syntax:

  • type: This is a TypeScript keyword used to create a new type alias.
  • NewType: This is the name you give to the new type alias that you're creating. You can replace it with any valid identifier.
  • =: This is the assignment operator used to assign the resulting instance type to your new type alias.
  • InstanceType<Type>: This is the utility type that extracts the instance type of a class or constructor function, where Type is the class or constructor function you want to work with.
TypeScript Course Instructor Image
TypeScript Course Instructor Image

Time To Transition From JavaScript To TypeScript

Level Up Your TypeScript And Object Oriented Programming Skills. The only complete TypeScript course on the marketplace you building TypeScript apps like a PRO.

SEE COURSE DETAILS

Real-World Use Cases

In real-world TypeScript applications, InstanceType<Type> can be used to extract instance types of classes and work with instances without explicitly defining their type. Let's consider an example where we have a class hierarchy with a base class and a derived class:

// Base class
class Animal {
name: string;

constructor(name: string) {
this.name = name;
}

speak(): string {
return `My name is ${this.name}`;
}
}

// Derived class
class Dog extends Animal {
bark(): string {
return "Woof! Woof!";
}
}

Now, let's say you want to write a function that takes a constructor function of any class that extends Animal and returns a new instance of that class. You can use InstanceType<Type> to achieve this:

function createInstance<T extends typeof Animal>(Ctor: T): InstanceType<T> {
return new Ctor("Buddy") as InstanceType<T>;
}

const dogInstance = createInstance(Dog);
console.log(dogInstance.speak());
// Output: My name is Buddy
console.log(dogInstance.bark());
// Output: Woof! Woof!

In this example, we define a generic function createInstance that takes a constructor function Ctor of any class extending Animal. The return type of this function is InstanceType<T>, where T is the constructor function type. This allows the function to return a new instance of the provided class, without having to explicitly define the instance type.

Combining InstanceType<Type> With Other Utility Types

In this example, we'll combine InstanceType<Type> with the Pick<Type, Keys> utility type in TypeScript. The Pick<Type, Keys> utility type allows you to create a new type by picking a set of properties Keys from an existing type Type.

Consider the following class hierarchy:

// Base class
class Vehicle {
make: string;
model: string;

constructor(make: string, model: string) {
this.make = make;
this.model = model;
}

getDetails(): string {
return `Make: ${this.make}, Model: ${this.model}`;
}
}

// Derived class
class Car extends Vehicle {
numberOfDoors: number;

constructor(make: string, model: string, numberOfDoors: number) {
super(make, model);
this.numberOfDoors = numberOfDoors;
}

getCarDetails(): string {
return `Make: ${this.make}, Model: ${this.model}, Number of doors: ${this.numberOfDoors}`;
}
}

Now, let's say we want to create a function that takes an instance of Car and returns an object containing only the make and model properties. We can use the InstanceType<Type> and Pick<Type, Keys> utility types to achieve this:

function getBasicDetails<T extends typeof Vehicle>(
instance: InstanceType<T>
): Pick<InstanceType<T>, "make" | "model"> {
const { make, model } = instance;
return { make, model };
}

const carInstance = new Car("Toyota", "Corolla", 4);
const basicDetails = getBasicDetails(carInstance);
console.log(basicDetails);
// Output: { make: 'Toyota', model: 'Corolla' }

In this example, we define a generic function getBasicDetails that takes an instance of a class extending Vehicle. The function returns an object with only the make and model properties, using the Pick<Type, Keys> utility type. The InstanceType<Type> utility type is used to infer the instance type of the provided class, which is passed to the Pick<Type, Keys> utility type.

What Can You Do Next 🙏😊

If you liked the article, consider subscribing to Cloudaffle, my YouTube Channel, where I keep posting in-depth tutorials and all edutainment stuff for software developers.

YouTube @cloudaffle