Die Eigenschaft 'Einträge' ist für den Typ 'ObjectConstructor' nicht vorhanden.

75

Ich arbeite an einer ng2-Implementierung. Ich verwende den folgenden Funktionsaufruf, um ein Objekt in ein Array zu konvertieren:

var authors = Object.entries(responseObject.Authors);

Dies ist eine Standard-js-Funktion. Der ts-Compiler gibt jedoch den folgenden Fehler zurück:

"Property 'entries' does not exist on type 'ObjectConstructor'"

Basierend auf einem schnellen Google-Ansatz scheint die Lösung darin zu bestehen, die compilerOptions-Zieleigenschaft von es5 in es6 zu ändern. Nach einigen früheren Recherchen für eine frühere Ausgabe dachte ich jedoch, dass ich die es6-Funktionalität nutzen kann, indem ich die zusätzliche Eigenschaft "lib" in meine tsconfig.json unten einbinde:

  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "module": "commonjs",
    "noEmitOnError": true,
    "noImplicitAny": false,
    "outDir": "../Scripts/",
    "removeComments": false,
    "sourceMap": true,
    "target": "es5",
    "moduleResolution": "node",
    "lib": [
      "es2015",
      "dom"
    ]
  }

Ich habe auch versucht, die Zieleigenschaft in es2015 zu ändern und dann das Projekt neu zu erstellen und "typescriptUsingTsConfig" auszuführen, aber ich erhalte immer noch den gleichen Fehler. Haben Sie eine Idee, was ich hier tun kann, um die Funktion Object.entries () zu nutzen?

user8334943
quelle

Antworten:

125

Sie haben völlig Recht, dass das Ändern targetder falsche Ansatz und das Ändern libder richtige Ansatz ist, Sie haben jedoch die falsche Version der Sprache angegeben. Nach MDN , Object.entrieswurde in der ES2017 - Spezifikation offiziell zugegeben.

"lib": ["es2017"]

ist daher das, was Sie stattdessen angeben müssen *.

Wenn Sie nur die Deklarationen für die Methoden der ObjectFunktion hinzufügen möchten, die in ES2017 hinzugefügt wurden, können Sie mit TypeScript einen detaillierteren Wert angeben .

"lib": ["es2017.object"]

Wie von Alexander Bird festgestellt, "lib"hängt der implizite Wert der Option standardmäßig von dem Wert ab, für den angegeben wurde, "target"falls vorhanden.

Zum Beispiel:

"target": "es2017"

Bewirkt, dass das entsprechende Präfix "lib.*"standardmäßig eingefügt "lib"wird, sofern nicht ausdrücklich angegeben.

Beachten Sie, dass Sie wahrscheinlich eine Polyfüllung der Implementierung selbst hinzufügen möchten, z. B. diese , um sicherzustellen, dass dies in älteren Laufzeiten funktioniert.

Hinweis: Alternativ können Sie eine spätere Version angeben

"lib": ["es2020"]

oder natürlich sogar

"lib": ["esnext"] 

Letzteres enthält die Deklarationen für die neuesten Standardbibliotheksfunktionen, die der TypeScript-Sprache bekannt sind. Da es sich um ein sich bewegendes Ziel handelt, sollte diese Option mit Vorsicht verwendet werden, da das Polyfilling der gesamten entsprechenden Laufzeit per Definition eine komplexe Aufgabe ist, die Nachforschungen erfordert und abhängig von Ihrer Ziellaufzeit möglicherweise unterschiedliche Polyfills lädt.

Darüber hinaus können Sie aufgrund der Array-Art der "lib"Option mehrere Werte kombinieren, um sie an Ihre Laufzeit anzupassen. Um beispielsweise es2015-fähige Webbrowser mit diesen Objektmethoden abzugleichen, die von einer Polyfüllung bereitgestellt werden, können Sie schreiben

"lib": ["es2015", "es2017.object", "dom"]

Hinweis: Einige Kommentatoren fragten, warum es falsch wäre, Änderungen vorzunehmen, --targetanstatt --libbeide zu verwenden, damit der Code die Typprüfung durchführen kann. Der Grund ist, dass sich --targetändert, wie der Code transpiliert wird. Dies "target": "es2017"bedeutet beispielsweise, dass asyncFunktionen für ältere Laufzeiten nicht transformiert werden. Dies ist falsch, da beabsichtigt wurde, die Verwendung zusätzlicher Bibliotheken zu ermöglichen und die Ausgabesyntax nicht zu ändern. Daher ist es wichtig, zwischen syntaktischen Merkmalen und Bibliotheksmerkmalen zu unterscheiden.

Aluan Haddad
quelle
1
@ user8334943 nein, Sie benötigen definitiv eine Polyfüllung für IE 10. Der MDN-Link enthält unten Informationen zur Browserunterstützung.
Aluan Haddad
1
Hinweis für andere: Wenn Sie die libCompileroption noch nicht verwendet haben, gibt es möglicherweise einen Standardwert basierend auf Ihrem Ziel, der beim Festlegen überschrieben wird lib. Eine Liste der Standardeinstellungen finden Sie in der Dokumentation zu den Compileroptionen . Ich musste auch explizit die Standardparameter libfür mein Ziel hinzufügen es2017.object.
Alexanderbird
1
@AluanHaddad sicher :) Ich bin damit einverstanden, so lange wie möglich auf dem Laufenden zu bleiben, und ich werde das Update bald durchführen. Dies ist eine große Anwendung mit vielen Entwicklern, daher müssen Aktualisierungen geplant werden. Danke für deinen Beitrag!
Jessy
1
Warum ist es korrekter, libstatt zu aktualisieren target?
rjh
1
@rjh Ziel ändert, wie der Code transpiliert wird. Dies "target": "es2017"bedeutet beispielsweise, dass asyncFunktionen für ältere Laufzeiten nicht transformiert werden. Dies ist falsch, da beabsichtigt wurde, die Verwendung zusätzlicher Bibliotheken zu ermöglichen und die Ausgabesyntax nicht zu ändern.
Aluan Haddad
9

Die akzeptierte Antwort hat bei mir nicht funktioniert, aber ich habe die Antwort aus der Eigenschaft 'zuweisen' angepasst. Sie existiert nicht für den Typ 'ObjectConstructor' wie folgt :

const changedFields = (<any>Object).entries(this.ngForm.form.controls)
                                   .filter(value => value[1].dirty);

Teilen für alle mit der gleichen Situation

Hien Nguyen
quelle
1
Danke Nguyen ...... Ich benutze Angular 6 mit Typoskript 2.6.2 und das hat bei mir funktioniert. Ich würde es lieben, wenn jemand es erklären könnte.
MichaelE
arbeitete für mich auf dem Typoskript-Spielplatz. Das ist ein ernstes Voodoo
Julian Suggate
Auf dem Typoskript-Spielplatz können Sie derzeit keine Einstellungen --lib--target--lib
vornehmen