Call & Construct Signatures
Describe objects that are themselves callable or constructable, like functions with extra properties.
In JavaScript, functions are objects β they can be called and carry properties. TypeScript can describe exactly that with call signatures and construct signatures inside an object type.
Call signature
Write the parameter list and return type with no name. This models a callable that also has fields:
interface Counter {
(): number; // callable: counter()
count: number; // and has a property
reset(): void;
}Construct signature
Prefix with new to describe something usable with new β handy for factories and passing classes around as values:
interface PointCtor {
new (x: number, y: number): { x: number; y: number };
}These signatures are how TypeScript types higher-order and factory code precisely instead of falling back to Function or any.
Example
When to use it
- A middleware factory type uses a call signature so the type checker verifies the factory is invoked correctly.
- A typed event emitter interface describes a callable property alongside regular methods on the same object.
- A class decorator type uses a construct signature to accept class constructors as arguments.
More examples
Call signature in an interface
An interface with a call signature describes an object that is both callable and has additional properties.
interface StringTransform {
(input: string): string; // call signature
description: string; // also has a property
}
const upper: StringTransform = Object.assign(
(s: string) => s.toUpperCase(),
{ description: 'Converts to uppercase' }
);
console.log(upper('hello')); // 'HELLO'
console.log(upper.description); // 'Converts to uppercase'Construct signature
A construct signature (new) lets a function accept any class constructor that matches the specified parameter shape.
interface Constructor<T> {
new (name: string): T;
}
class User {
constructor(public name: string) {}
}
function create<T>(Ctor: Constructor<T>, name: string): T {
return new Ctor(name);
}
const user = create(User, 'Alice');Overloaded call signatures
Multiple call signatures in one interface describe an overloaded callable, each with its own parameter/return type pair.
interface Formatter {
(value: number): string;
(value: string): string;
locale: string;
}
const fmt = Object.assign(
(v: number | string) => String(v),
{ locale: 'en-US' }
) as Formatter;
fmt(42); // string
fmt('hello'); // string
Discussion