web-dev-qa-db-fra.com

'nouvelle' expression, dont la cible n'a pas de signature de construction en TypeScript

Nous avons les TestComponent.ts Classe TypeScript:

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: }

Et ce qui suit TestVectorLayer.ts une fonction:

Gardez à l'esprit que OpenLayer 3 utilise la bibliothèque de fermeture de Google, c'est pourquoi TestVectorLayer n'est pas une classe TypeScript.

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; 

Nous obtenons l'erreur suivante:

Error on Line 08 in TestComponent.ts class:

[ts] l'expression 'new', dont la cible n'a pas de signature de construction, a implicitement un type 'any'. importer TestVectorLayer

Le package.json versions de TypeScript:

devDependencies:

"TypeScript": "~2.2.1"
18
fuzz

Voici une simplification de la question:

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

const layer = new TestVectorLayer("");

L'erreur se produit car TestVectorLayer n'a pas de nouvelle signature, donc layer est implicitement tapé comme any. Que des erreurs avec --noImplicitAny.

Vous pouvez résoudre ce problème en passant à une classe, mais dans votre cas, cela semble un peu plus compliqué car l'héritage est effectué par le framework sous-jacent. Pour cette raison, vous devrez faire quelque chose d'un peu plus compliqué et ce n'est pas idéal:

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; 

Puis dans le fichier avec TestComponent:

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

La réponse de David est excellente, mais si vous vous souciez de la faire rapidement compiler (par exemple parce que vous migrez de JS vers TS), vous pouvez simplement y mettre any pour fermer le compilateur plaintif.

Fichier TS:

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

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

compile dans ce fichier JS:

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

Faites juste attention à ne pas faire cette erreur:

Fichier TS:

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

Résultat JS:

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

et c'est faux. Vous obtiendrez une erreur TypeError: TestConstructor(...) is not a constructor lors de l'exécution.

8
Mariusz Pawelski