'new' expression, whose target lacks a construct signature in TypeScript

JavascriptTypescript

Javascript Problem Overview


We have the following TestComponent.ts TypeScript class:

01: import TestVectorLayer from './TestVectorLayer'
02: 
03: export class TestComponent implements OnInit {
04:   private foo: any;
05: 
06:   constructor() { }
07: 
08:   const layer = new TestVectorLayer("foo");
09: }

And the following TestVectorLayer.ts function:

Keep in mind that OpenLayer's 3 is using the Google Closure Library, that's why TestVectorLayer is not a TypeScript class.

01: declare let ol: any;
02:
03: const TestVectorLayer = function (layerName: string) {
04:   ...
05:   console.log(layerName);
06:
07:   ol.layer.Image.call(this, opts);
08: }
09:
10: ol.inherits(TestVectorLayer as any, ol.layer.Image as any);
11:
12: export default TestVectorLayer; 

We're getting the following error:

Error on Line 08 in TestComponent.ts class:

> [ts] 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. import TestVectorLayer

The package.json versions of TypeScript:

devDependencies:

"typescript": "~2.2.1"

Javascript Solutions


Solution 1 - Javascript

David answer is great, but if you care just about quickly making it compile (for example because you are migrating from JS to TS) then you can simply put any there to shut up complaining compiler.

TS file:

const TestConstructorFunction = function (this: any, a: any, b: any) {
    this.a = a;
    this.b = b;
};

let test1 = new (TestConstructorFunction as any)(1, 2);

compiles to this JS file:

var TestConstructor = function (a, b) {
    this.a = a;
    this.b = b;
};
var test1 = new TestConstructor(1, 2);

Just pay attention to not make this mistake:

TS file:

// wrong!
let test2 = new (TestConstructorFunction(1, 2) as any);

JS result:

// wrong!
var test2 = new (TestConstructor(1, 2));

and this is wrong. You'll get TypeError: TestConstructor(...) is not a constructor error at runtime.

Solution 2 - Javascript

Here's a simplification of the question:

const TestVectorLayer = function(layerName: string) {
};

const layer = new TestVectorLayer("");

The error is happening because TestVectorLayer doesn't have a new signature, so layer is implicitly typed as any. That errors with --noImplicitAny.

You can fix this by switching to a class, but in your case this seems a bit more complicated because the inheritance is done by the underlying framework. Because of that, you will have to do something a bit more complicated and it's not ideal:

interface TestVectorLayer {
  // members of your "class" go here
}

const TestVectorLayer = function (this: TestVectorLayer, layerName: string) {
  // ...
  console.log(layerName);
  ol.layer.Image.call(this, opts);
} as any as { new (layerName: string): TestVectorLayer; };

ol.inherits(TestVectorLayer, ol.layer.Image);

export default TestVectorLayer; 

Then in the file with TestComponent:

const layer = new TestVectorLayer(layerName); // no more compile error

Solution 3 - Javascript

In my case, You have to define it as any and has new signature, for example.

const dummyCtx = function(txt: string) {
  this.foo = txt
} as any as { new (txt: string): any }

// just use it as usual
const dctx = new dummyCtx('bar')

Solution 4 - Javascript

I would give your TestVectorLayer an interface

class TestVectorLayer implements TestVectorLayer {
    
}

interface TestVectorLayer {
    new (layerName: string): TestVectorLayer;
} 

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionfulvioView Question on Stackoverflow
Solution 1 - JavascriptMariusz PawelskiView Answer on Stackoverflow
Solution 2 - JavascriptDavid SherretView Answer on Stackoverflow
Solution 3 - JavascriptAditya Kresna PermanaView Answer on Stackoverflow
Solution 4 - Javascriptrob_jamesView Answer on Stackoverflow