Typescript: Extending a short hand ambient module import

Created on 16 Dec 2016  ·  3Comments  ·  Source: microsoft/TypeScript



TypeScript Version: 2.1.1

Code

declare module 'base';

```ts
import * as Base from 'base';

class Derived extends Base { // error TS2507: Type 'any' is not a constructor function type.
}

**Expected behavior:**

An easy concise way of declaring a module so that the base import can be extended

**Actual behavior:**

error TS2507: Type 'any' is not a constructor function type.

In order to get around the error, I have to do something like this:

```ts
declare module 'base' {
  interface Constructor {
      new (...args: any[]): this;
  }

  const _: Constructor;
  export = _;
}
Design Limitation

Most helpful comment

In my experience this is a huge point of friction for JavaScript teams working on existing code-bases dipping their toes into the statically typed world. They're almost immediately hit with the need to:

  • understand how to write types for 3rd party modules
  • understand how legacy commonjs modules are described in TS (e.g. exports = …)
  • understand @types/ and how to deal:

    • versioning
    • working around incorrect types
    • dependency vs devDependency

It would be great if instead extending an any type worked.

the type system does not know what extending any really means. does it mean that the class is any or how would a super call be...

I'd be fine with the class being an any.

All 3 comments

this is the same as:

var a: any;
class C extends a {}

the type system does not know what extending any really means. does it mean that the class is any or how would a super call be...

you can cast to a class/constructor function if you need to e.g.

declare class B { }
const constructor = a as typeof B;

class C extends constructor { 
}

or just define the class on the module.

@mhegazy Those solutions are all very verbose when declaring many modules as an interim step in converting a large javascript codebase.

It would be better to have the short hand module declaration export a more inclusive any object which allowed one to extend it. I can already call new on the import, but can't extend it? e.g. the following generates no error:

import * as Base from 'base';

const base = new Base();

In my experience this is a huge point of friction for JavaScript teams working on existing code-bases dipping their toes into the statically typed world. They're almost immediately hit with the need to:

  • understand how to write types for 3rd party modules
  • understand how legacy commonjs modules are described in TS (e.g. exports = …)
  • understand @types/ and how to deal:

    • versioning
    • working around incorrect types
    • dependency vs devDependency

It would be great if instead extending an any type worked.

the type system does not know what extending any really means. does it mean that the class is any or how would a super call be...

I'd be fine with the class being an any.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Roam-Cooper picture Roam-Cooper  ·  3Comments

jbondc picture jbondc  ·  3Comments

fwanicka picture fwanicka  ·  3Comments

Antony-Jones picture Antony-Jones  ·  3Comments

weswigham picture weswigham  ·  3Comments