Skip to main content

Can you overload a constructor?

1. The general idea of constructor overloading

In TypeScript you can declare several constructor signatures, but implement only one (real) constructor with checks inside it:

javascript
class User { name: string; age?: number; // Overloads (type-level only) constructor(name: string); constructor(name: string, age: number); // A single implementation constructor(name: string, age?: number) { this.name = name; this.age = age; } } const u1 = new User("Tim"); // works const u2 = new User("Alex", 25); // works const u3 = new User(); // Error: no matching overload

The constructor(...) overloads above are only type signatures. The last constructor(...) with a body is the real implementation.


2. How this works under the hood

TypeScript compiles everything into a single JavaScript constructor, and the overloads are needed only for type checking at compile time.

javascript
// TS class User { constructor(name: string); constructor(name: string, age: number); constructor(name: string, age?: number) { console.log(name, age); } }

Compiles to JS as:

javascript
class User { constructor(name, age) { console.log(name, age); } }

The type checks are removed, and a single constructor remains.


3. Checking arguments inside the constructor

Since JS does not support "real" overloading, manual checks are usually done inside the constructor:

javascript
class Point { x: number; y: number; constructor(x: number); constructor(x: number, y: number); constructor(x: number, y?: number) { if (y === undefined) { this.x = this.y = x; // if one argument was passed } else { this.x = x; this.y = y; } } } new Point(5); // (5, 5) new Point(5, 10); // (5, 10)

4. Overloading with different parameter types

You can overload a constructor by type, not only by the number of arguments:

javascript
class FileData { path: string; buffer?: Uint8Array; constructor(path: string); constructor(buffer: Uint8Array); constructor(value: string | Uint8Array) { if (typeof value === "string") { this.path = value; } else { this.buffer = value; this.path = "memory.bin"; } } } new FileData("file.txt"); // string new FileData(new Uint8Array([1, 2])); // Uint8Array new FileData(123); // A type error

5. Overloading via union types (an alternative)

Sometimes overloads can simply be replaced with a union of types (|):

javascript
class User { constructor(public name: string | number) {} } new User("Tim"); new User(123);

But then TS does not distinguish the signatures, and the types must be resolved manually inside the constructor.


6. Constructor overloading in a base and a derived class

You can overload a constructor in a parent class and call the right one via super():

javascript
class Shape { color: string; constructor(); constructor(color: string); constructor(color = "black") { this.color = color; } } class Circle extends Shape { radius: number; constructor(radius: number); constructor(radius: number, color: string); constructor(radius: number, color?: string) { super(color); this.radius = radius; } } const c1 = new Circle(10); const c2 = new Circle(10, "red");

7. An important nuance: overloads are not runtime overloading

All the signatures are checked only by the compiler and do not exist in the compiled code:

  • TypeScript checks the correct number and types of arguments.
  • JavaScript executes a single constructor with checks inside it.
  • You cannot have two implementations of a constructor.

Summary

CapabilitySupportedComment
Several constructor signaturesYesChecked by the compiler
Several constructor implementationsNoOnly one, with a body
Overloading by number of argumentsYesVia ? or checks
Overloading by typeYesVia unions or signatures
Real runtime overloading (as in C#/Java)NoNot possible
Type checking at newYesWorks thanks to the signatures

In short:

In TypeScript you can overload constructors, but only at the type level. The implementation is always a single one, and you check the arguments yourself inside it.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.