# How to Define a Generic TypeScript Class Constructor Type

> Learn to define a generic TypeScript class constructor type using callable signatures. Understand how to create constructors for generic types and support abstract classes effectively.

- Repository: [Microsoft/TypeScript](https://github.com/microsoft/typescript)
- Tags: how-to-guide
- Published: 2026-02-13

---

**Define a generic class constructor type in TypeScript using the callable signature pattern `new (...args: any[]) => T`, which the compiler recognizes as a constructor that produces an instance of type `T`, and optionally prefix with `abstract` to support abstract base classes.**

TypeScript models class constructors as callable signatures that return class instances, with the microsoft/TypeScript repository defining these patterns in its core library files. Understanding how to create generic typescript class constructor types enables you to build flexible factory functions, mixin utilities, and decorator implementations that work with any class structure.

## Understanding Constructor Signatures in TypeScript

TypeScript represents constructors through specific callable signatures defined in [`src/lib/es5.d.ts`](https://github.com/microsoft/TypeScript/blob/main/src/lib/es5.d.ts). The language distinguishes between concrete and abstract instantiation patterns:

- **`new (...args: any[]) => T`** — A concrete constructor that can be invoked with the `new` keyword to produce an instance of type `T` (defined at line 1622)
- **`abstract new (...args: any[]) => T`** — An abstract constructor signature representing classes that cannot be instantiated directly but can be extended (defined at line 1627)

The compiler differentiates these signatures in [`src/compiler/checker.ts`](https://github.com/microsoft/TypeScript/blob/main/src/compiler/checker.ts) around line 7400, where the type-checking logic enforces that `abstract new` signatures cannot be called directly while still allowing them in type positions for inheritance.

## Creating a Reusable Generic Constructor Type

You can encapsulate constructor signatures into reusable type aliases that accept generic parameters for both the instance type and arguments.

### Concrete vs Abstract Constructors

Define a generic constructor type alias for concrete classes:

```typescript
type Ctor<T = any, A extends any[] = any[]> = new (...args: A) => T;

```

For abstract classes that serve as base classes, use the `abstract` modifier:

```typescript
type AbstractCtor<T = any, A extends any[] = any[]> = abstract new (...args: A) => T;

```

In these definitions:
- `T` represents the instance type created by the constructor
- `A` constrains the tuple of argument types (defaulting to `any[]`)

## Leveraging Built-in Utility Types

TypeScript provides built-in utilities in [`src/lib/es5.d.ts`](https://github.com/microsoft/TypeScript/blob/main/src/lib/es5.d.ts) that simplify constructor type definitions without manual signature replication:

- **`ConstructorParameters<T>`** (line 1627) — Extracts the parameter tuple type from a constructor `T`
- **`InstanceType<T>`** (line 1637) — Extracts the instance type produced by a constructor `T`

Combine these to derive constructor types from existing classes:

```typescript
type CtorFrom<T> = new (...args: ConstructorParameters<T>) => InstanceType<T>;

```

This approach automatically infers both the arguments and return type from the source class.

## Practical Code Examples

### Generic Factory Function

Use a constructor type alias to build a factory that instantiates any class:

```typescript
type Ctor<T, A extends any[] = any[]> = new (...args: A) => T;

class Factory {
  static create<T, A extends any[]>(
    ctor: Ctor<T, A>,
    ...args: A
  ): T {
    return new ctor(...args);
  }
}

// Usage
class Point {
  constructor(public x: number, public y: number) {}
}

const p = Factory.create(Point, 10, 20); // Point { x: 10, y: 20 }

```

The `Ctor` alias mirrors the primitive definition found in [`src/lib/es5.d.ts`](https://github.com/microsoft/TypeScript/blob/main/src/lib/es5.d.ts).

### Handling Abstract Classes

When working with abstract base classes, use `AbstractCtor` to accept both concrete and abstract constructors:

```typescript
type AbstractCtor<T = any, A extends any[] = any[]> = abstract new (...args: A) => T;

function subclass<TBase extends AbstractCtor>(Base: TBase) {
  return class Derived extends Base {
    // Additional implementation
  };
}

// Example
abstract class Shape {
  abstract area(): number;
}

const Circle = subclass(Shape); // Valid: Shape is abstract

```

This pattern aligns with the compiler's handling of `abstract new` signatures in [`src/compiler/checker.ts`](https://github.com/microsoft/TypeScript/blob/main/src/compiler/checker.ts), allowing abstract classes to appear in type constraints while preventing direct instantiation.

### Extracting Types with Utilities

Leverage `ConstructorParameters` and `InstanceType` to extract and reuse constructor signatures:

```typescript
class Box {
  constructor(public width: number, public height: number) {}
}

// Resolves to: new (width: number, height: number) => Box
type BoxCtor = new (...args: ConstructorParameters<typeof Box>) => InstanceType<typeof Box>;

```

These utilities are defined at lines 1627 and 1637 in [`src/lib/es5.d.ts`](https://github.com/microsoft/TypeScript/blob/main/src/lib/es5.d.ts).

### Decorator Metadata Patterns

The decorators library in [`src/lib/decorators.d.ts`](https://github.com/microsoft/TypeScript/blob/main/src/lib/decorators.d.ts) (line 27) provides a `Class` alias for abstract constructors:

```typescript
type Class<T = any> = abstract new (...args: any[]) => T;

function sealed<T extends Class>(target: T) {
  Object.seal(target);
  Object.seal(target.prototype);
}

```

This shorthand represents "any abstract constructor" and is used throughout TypeScript's decorator metadata implementation.

## How the TypeScript Compiler Processes Constructors

The distinction between concrete and abstract constructor types is enforced by the type checker in [`src/compiler/checker.ts`](https://github.com/microsoft/TypeScript/blob/main/src/compiler/checker.ts) around line 7400. This logic ensures that:

- Concrete constructors (`new (...) => T`) can be invoked with the `new` keyword
- Abstract constructors (`abstract new (...) => T`) are valid for subclassing but reject direct instantiation

Test cases in [`tests/cases/conformance/classes/mixinAbstractClasses.ts`](https://github.com/microsoft/TypeScript/blob/main/tests/cases/conformance/classes/mixinAbstractClasses.ts) demonstrate how these signatures participate in mixin inference, while [`tests/cases/conformance/override/override19.ts`](https://github.com/microsoft/TypeScript/blob/main/tests/cases/conformance/override/override19.ts) illustrates simple abstract constructor aliases in type-compatibility scenarios.

## Summary

- Define **generic typescript class constructor types** using the `new (...args: A) => T` callable signature pattern
- Prefix with `abstract` to support base classes that cannot be instantiated directly
- Use `ConstructorParameters<T>` and `InstanceType<T>` from [`src/lib/es5.d.ts`](https://github.com/microsoft/TypeScript/blob/main/src/lib/es5.d.ts) to extract constructor components from existing types
- Reference [`src/lib/decorators.d.ts`](https://github.com/microsoft/TypeScript/blob/main/src/lib/decorators.d.ts) for the `Class<T>` alias when working with decorator metadata
- Remember that [`src/compiler/checker.ts`](https://github.com/microsoft/TypeScript/blob/main/src/compiler/checker.ts) enforces the distinction between concrete and abstract constructor signatures

## Frequently Asked Questions

### What is the difference between new and abstract new in TypeScript?

The `new` signature represents a concrete constructor that can be called with the `new` keyword to create instances, while `abstract new` represents an abstract constructor that can only be used for typing and subclassing. According to the TypeScript source code in [`src/compiler/checker.ts`](https://github.com/microsoft/TypeScript/blob/main/src/compiler/checker.ts), the compiler treats these differently by prohibiting direct instantiation of abstract constructors while allowing them in extends clauses.

### How do I extract constructor parameter types in TypeScript?

Use the built-in utility type `ConstructorParameters<T>` defined in [`src/lib/es5.d.ts`](https://github.com/microsoft/TypeScript/blob/main/src/lib/es5.d.ts) at line 1627. This utility extracts the parameter tuple type from a constructor type, allowing you to reference the arguments required to instantiate a class without manually redefining them.

### Can I use generic constructor types with mixins?

Yes, generic constructor types are essential for mixin patterns. The test file [`tests/cases/conformance/classes/mixinAbstractClasses.ts`](https://github.com/microsoft/TypeScript/blob/main/tests/cases/conformance/classes/mixinAbstractClasses.ts) in the TypeScript repository demonstrates how abstract constructor signatures enable mixin functions to accept both concrete and abstract base classes while preserving type inference for the resulting composed class.

### Where are the built-in constructor utility types defined?

The core constructor utility types `ConstructorParameters` and `InstanceType` are defined in [`src/lib/es5.d.ts`](https://github.com/microsoft/TypeScript/blob/main/src/lib/es5.d.ts) at lines 1627 and 1637 respectively. Additionally, the `Class` type alias used for decorator metadata is defined in [`src/lib/decorators.d.ts`](https://github.com/microsoft/TypeScript/blob/main/src/lib/decorators.d.ts) at line 27 as an abstract constructor signature.