Skip to main content

Typing a constructor

1. Basic typing of constructor parameters

javascript
class User { name: string; age: number; constructor(name: string, age: number) { this.name = name; this.age = age; } }

Here the constructor parameters name and age have explicitly specified types. TypeScript checks:

  • that when creating an instance with new User(...), correct types are passed;
  • that the class fields and constructor parameters are compatible.
javascript
const u1 = new User("Tim", 25); // OK const u2 = new User(25, "Tim"); // Error: types don't match

2. Shorthand notation via modifiers

TypeScript allows you to automatically declare and initialize properties directly in the constructor parameters:

javascript
class User { constructor(public name: string, private age: number) {} }

This is equivalent to:

javascript
class User { public name: string; private age: number; constructor(name: string, age: number) { this.name = name; this.age = age; } }

Modifiers you can use:

  • public - the property is accessible everywhere
  • private - accessible only inside the class
  • protected - accessible inside the class and its subclasses
  • readonly - read-only (cannot be changed after initialization)

Example:

javascript
class Point { constructor( public readonly x: number, public readonly y: number ) {} } const p = new Point(5, 10); p.x = 8; // Error: readonly

3. Default and optional parameters

javascript
class User { constructor( public name: string, public age: number = 18, public city?: string ) {} } new User("Tim"); // age = 18, city = undefined new User("Alex", 25, "Paris");

In TypeScript, all the standard rules for function parameters also apply to constructors.


4. Typing the constructor itself as a function

Sometimes you need to type the constructor itself, for example, when passing a class as an argument:

javascript
type Constructor<T> = new (...args: any[]) => T; function createInstance<T>(Ctor: Constructor<T>): T { return new Ctor(); } class User { constructor(public name = "Tim") {} } const u = createInstance(User); // User

5. The constructor parameter type extracted via the ConstructorParameters utility

TypeScript provides a built-in utility type:

javascript
type ConstructorParameters<T> = T extends new (...args: infer P) => any ? P : never;

Example:

javascript
class User { constructor(public name: string, public age: number) {} } type Params = ConstructorParameters<typeof User>; // [string, number] const args: Params = ["Tim", 25]; const u = new User(...args); // OK

This works via infer, extracting the parameter types from the constructor.


6. The type of the constructor's result (InstanceType)

If you need to get the instance type, use the InstanceType utility:

javascript
class User { constructor(public name: string, public age: number) {} } type UserInstance = InstanceType<typeof User>; // { name: string; age: number; } const u: UserInstance = new User("Tim", 25);

7. Constructors with generic parameters

javascript
class Box<T> { constructor(public value: T) {} } const strBox = new Box<string>("Hello"); const numBox = new Box(123); // T = number (inference)

Summary

CapabilityExampleWhat it does
Regular typingconstructor(name: string, age: number)A simple type declaration
Shorthand formconstructor(public name: string)Automatically creates a field
Optional parametersconstructor(name: string, age?: number)The parameter can be omitted
Default parametersconstructor(name: string, age = 18)A default value
Constructor typetype Ctor<T> = new (...args: any[]) => TDefines the "class type"
Extracting parametersConstructorParameters<typeof C>Gets [type_1, type_2, ...]
Instance typeInstanceType<typeof C>Gets the type of a class instance

Short Answer

Interview ready
Premium

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