„neuer“ Ausdruck, dessen Ziel in TypeScript keine Konstruktsignatur aufweist

Lesezeit: 5 Minuten

Benutzeravatar von fulvio
Fulvio

Wir haben folgendes TestComponent.ts TypeScript-Klasse:

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

Und die folgende TestVectorLayer.ts Funktion:

Denken Sie daran, dass OpenLayer 3 die Google Closure Library verwendet, deshalb TestVectorLayer ist keine TypeScript-Klasse.

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; 

Wir erhalten den folgenden Fehler:

Error on Line 08 in TestComponent.ts class:

[ts] ‘new’-Ausdruck, dessen Ziel keine Konstruktsignatur hat, hat implizit einen ‘any’-Typ. TestVectorLayer importieren

Das package.json Versionen von TypeScript:

Entwicklungsabhängigkeiten:

"typescript": "~2.2.1"

  • Und wenn Sie wollen new es warum nicht TestVectorLayer Klasse sein?

    – Saravana

    26. April 2017 um 1:57 Uhr

  • @Saravana das sollte keine Rolle spielen, am Ende des Tages ist der Unterricht nur syntaktischer Zucker.

    – WilomGfx

    26. April 2017 um 1:59 Uhr


  • @AluanHaddad Ich habe die Frage aktualisiert. TestVectorLayer verwendet OpenLayer 3, das die Google Closure Library verwendet.

    – Fulvo

    26. April 2017 um 2:00 Uhr


  • @fuzz also verwendest du --allowJs? Ich bin immer noch etwas verwirrt, denn wenn es sich um eine Bibliothek eines Drittanbieters handelt, warum verbrauchen Sie sie aus einem relativen Pfad und nicht aus ihrem Paket mit ihren package.json- und Lizenzdateien?

    – Aluan Haddad

    26. April 2017 um 2:05 Uhr


  • @Saravana Stimmt, würde in der Tat nicht schaden, eine Klasse zu machen. Nur für die Schreibvorteile.

    – WilomGfx

    26. April 2017 um 2:06 Uhr

Die Antwort von David ist großartig, aber wenn es Ihnen nur darum geht, sie schnell zu kompilieren (z. B. weil Sie von JS zu TS migrieren), können Sie einfach sagen any dort, um den Compiler zum Schweigen zu bringen.

TS-Datei:

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

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

kompiliert zu dieser JS-Datei:

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

Achten Sie nur darauf, diesen Fehler nicht zu machen:

TS-Datei:

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

JS-Ergebnis:

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

und das ist falsch. Du wirst kriegen TypeError: TestConstructor(...) is not a constructor Fehler zur Laufzeit.

  • Ich migriere von einem sehr alten JS und das wäre in meinem Fall die richtige Antwort.

    Benutzer3025289

    2. Juni 2020 um 14:43 Uhr

  • vielen Dank, es funktioniert! const s1 = new (Student as any)('elite', 23);

    – xgqfrms

    3. Juni 2020 um 17:47 Uhr


  • hat meinen Tag gerettet! Ich muss es für eine Klasse zum Laufen bringen, die ich nicht geschrieben habe

    – Jack

    16. März um 4:44 Uhr

  • Diese Nischenantwort hat also mehr Likes bekommen als die richtige. Dies ist ein wenig alarmierend, da Neulinge denken könnten, dass dies ein normaler Ansatz ist. Es ist ein Cheat, der ein wenig besser ist als @ts-ignore.

    – Onkeltem

    2. April um 13:02 Uhr


  • @Onkeltem Ja, hat mich auch überrascht, dass es mehr Likes bekommen hat. Nun, die Leute wollen den Compilerfehler beheben und weitermachen. Ich kann es ihnen nicht verübeln. Ich denke, es ist besser, als Typescript überhaupt nicht zu verwenden 😉 Die akzeptierte Antwort ist eindeutig besser, da sie die richtige Typdefinition für die Funktion bereitstellt und daher überhaupt typgeprüft ist new FunCtr(...) Anrufe. Aber wenn Sie nur einen Ort reparieren müssen, an dem es heißt, dann denke ich, dass es keine so große Sache ist. IMO verwenden as any sollte im Allgemeinen als schlechte Praxis angesehen werden, aber manchmal möchte man einfach den Compiler schließen und weitermachen …

    – Mariusz Pawelski

    3. April um 18:03 Uhr


Benutzeravatar von David Sherret
David Sherret

Hier eine Vereinfachung der Frage:

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

const layer = new TestVectorLayer("");

Der Fehler tritt auf, weil TestVectorLayer hat keine neue Signatur, also layer ist implizit als typisiert any. Dass Fehler mit --noImplicitAny.

Sie können dies beheben, indem Sie zu einer Klasse wechseln, aber in Ihrem Fall scheint dies etwas komplizierter zu sein, da die Vererbung durch das zugrunde liegende Framework erfolgt. Aus diesem Grund müssen Sie etwas komplizierter vorgehen und es ist nicht 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; 

Dann in der Datei mit TestComponent:

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

  • Ihre kompliziertere, aber nicht ideale Lösung funktioniert. 🙂 Vielen Dank für die Bereitstellung einer vorübergehenden Lösung. Wir werden versuchen, auf einen Klassenwechsel hinzuarbeiten. Ursprünglich sind wir auf eine Klasse umgestiegen und haben eine ganze Reihe von Problemen mit der Vererbung festgestellt, deshalb haben wir uns für den hybriden Ansatz von JS- und TS-Annotationen entschieden.

    – Fulvo

    26. April 2017 um 3:22 Uhr


  • @Fuzz kein Problem! Es könnte einen besseren Weg geben … fällt mir im Moment nur keiner ein.

    – David Sherret

    26. April 2017 um 3:32 Uhr

  • @DavidSherret können Sie bitte mitteilen, wo ich weitere Informationen/Dokumente erhalten kann as any as

    – Sohel Ahmed Mesaniya

    16. Mai 2019 um 10:08 Uhr

  • @SohelAhmedM Lesen Sie mehr über Typzusicherungen hier. as any ist eine Typaussage an die any Typ. Tun value as any as T ist zwei Typ-Assertionen und ist eine Möglichkeit, den Typ von zu behaupten value wie T wenn die Art von value kann nicht behauptet werden T (zB wann value as T würde einen Kompilierfehler verursachen, aber Sie möchten es trotzdem behaupten). Im Wesentlichen ist es eine Möglichkeit, die Typprüfung zu umgehen.

    – David Sherret

    17. Mai 2019 um 0:33 Uhr

  • Man muss Typoskript lieben. Wie viele Stunden werden verschwendet, wenn man versucht, dieses Zeug herauszufinden?

    – png

    18. November 2020 um 20:17 Uhr

In meinem Fall müssen Sie es als definieren any und hat new Unterschrift zum Beispiel.

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')

  • typescriptlang.org/docs/handbook/2/… Ich habe die Typoskript-Dokumente durchgelesen und bin auf das Problem wie in der obigen Frage gestoßen. Dies hat das Problem für mich tatsächlich gelöst.

    – Melvin Tehubijuluw

    20. Dezember 2021 um 14:30 Uhr


Ich würde Ihrem TestVectorLayer eine Schnittstelle geben

class TestVectorLayer implements TestVectorLayer {
    
}

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

1404760cookie-check„neuer“ Ausdruck, dessen Ziel in TypeScript keine Konstruktsignatur aufweist

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy