Skip to content

Suggestion: Merge ambient function and class declarations with the same name. #2959

Closed
@rbuckton

Description

@rbuckton

Summary

To better support subclassing built-ins, and still support built-ins and pre-ES6 "classes" that can also be called as functions, we should be able to merge the call signatures of ambient function declarations with the static side of a class declaration.

Current state

Currently, if you want to declare an ambient "class" that has both call and construct signatures, you need to use an interface-interface-var pattern, as follows:

// instance-side interface type
interface Array<T> { /*...*/ }

// static-side interface type
interface ArrayConstructor {
  <T>(length: number): T[];
  new <T>(length: number): T[];
  /* ... */
}

// value declaration for constructor
declare var Array: ArrayConstructor;

This is a problem, however as "classes" defined using this pattern cannot be used in the extends clause of a class declaration in TypeScript.

Proposal

Merge ambient function and class declarations with the same name. Ambient function declarations with the same name as an ambient class declaration in the same lexical scope would contribute their call signatures to the static side of the class declaration. For example:

// lib.d.ts
declare function Array<T>(length: number): T[];
declare class Array<T> {
  constructor(length: number);
}

// app.ts
var ar1 = Array(10); // T[]
var ar2 = new Array(10); // T[]

Out of scope

Metadata

Metadata

Assignees

No one assigned

    Labels

    SuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions