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"
So an interface with a construct signature defines the signature of a constructor! The constructor of your class that should comply with the signature defined in the interface(think of it as the constructor implements the interface).
A constructor is a special function of the class that is responsible for initializing the variables of the class. TypeScript defines a constructor using the constructor keyword. A constructor is a function and hence can be parameterized. The this keyword refers to the current instance of the class.
declare class is for when you want to describe an existing class (usually a TypeScript class, but not always) that is going to be externally present (for example, you have two . ts files that compile to two . js files and both are included via script tags in a webpage).
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With