Die Eigenschaft 'assign' ist für den Typ 'ObjectConstructor' nicht vorhanden.


130

Ich verwende TypeScript in meiner Anwendung, in der ich folgende Funktionen verwende:

Object.assign(this.success, success.json())

Während der Kompilierung erhalte ich jedoch die folgende Fehlermeldung:

 error TS2339: Property 'assign' does not exist on type 'ObjectConstructor'.

Haben Sie eine Idee, wie ich diesen Fehler beseitigen kann?


Bitte erwägen Sie, die akzeptierte Antwort zu ändern. Seitdem wurden viel bessere Antworten mit mehr Upvotes veröffentlicht.
— mindplay.dk

Antworten:


129

Sie können die Typzusicherung wie folgt verwenden:

(<any>Object).assign(this.success, success.json())

30
Wow, scheint super hackig zu sein. Können Sie erklären, was (<any> Object) macht?
— Uksz

Okay, ich sehe, dass ich erkläre, dass Object den Typ any hat.
— Uksz

31
Obwohl dies eine Lösung zu sein scheint, sollte es wirklich nicht als eine behandelt werden. Anstatt einfach Mehrdeutigkeiten hinzuzufügen und Transpilerfehler zu verbergen (was dies tut), ist es weitaus besser, sie tatsächlich zu beheben und nützliches Feedback von der Konsole zu erhalten.
— Dmitry Parzhitsky

6
Dies ist nur das Casting und Verstecken des Problems. Sie müssen möglicherweise Polyfills in bestimmten Browsern usw. verwenden. Dies führt zu Fehlern, die in einigen Browsern ausgeführt werden
— Tom McKearney

3
Ich würde jedem, der hier sucht, raten, etwas weiter nach unten zu scrollen, wo erklärt wird, was zu Ihrer hinzugefügt werden soll. tsconfigDies ist eine bessere Lösung als diese.
— Mesqueeb

175

Konfigurieren:

Wenn Sie VS-Code verwenden (oder wenn Sie eine tsconfig.jsonDatei sehen):

Sie sollten die libEigenschaft zu Ihrer hinzufügen , tsconfig.jsonund dann verwendet Ihr Editor die gebündelten Typoskript-Typdefinitionen und gibt Ihnen auch Intellisense.

Fügen Sie einfach den "lib": ["esnext", "dom"]zu Ihrem hinzu tsconfig.jsonund starten Sie VS Code neu

{
    "compilerOptions": {
        // ...
        "target": "es5",
        "lib": ["esnext", "dom"]
        // ...
    }
}

Alle tsconfig.jsonOptionen finden Sie hier .

Wenn Sie Visual Studio oder MSBuild verwenden, fügen Sie dieses Tag hinzu:

<TypeScriptLib>esnext, dom</TypeScriptLib>

Alle MSBuild Typoskript Compiler - Optionen und die Verwendung hier .


Überprüfe deine Arbeit:

Wenn Sie Ihr Projekt für die Verwendung der integrierten Typen konfiguriert und Ihren Editor neu gestartet haben, sieht der resultierende Typ wie folgt aus, anstatt des Typs, den anySie verwenden Object.assign:

Codebeispiel 1


Hinweis zu Polyfills und der Kompatibilität älterer Browser:

Beachten Sie, dass Sie Polyfills einschließen müssen, wenn Sie auf ES5 oder niedriger transpilieren und auf IE11 abzielen, da der Typoskript-Compiler die Polyfills für Sie nicht enthält.

Wenn Sie die Polyfills einschließen möchten (was Sie sollten), würde ich empfehlen, die Polyfills von core-js zu verwenden.

npm install --save core-js

oder

yarn add core-js

Fügen Sie dann am Einstiegspunkt in Ihrer App (z. B. /src/index.ts) den Import für core-jsoben in der Datei hinzu:

import 'core-js';

Wenn Sie keinen Paketmanager verwenden, können Sie die folgende aus MDN entnommene Polyfüllung einfach an einer Stelle in Ihren Code einfügen, die vor Ihrer Verwendung von ausgeführt wird Object.assign.

if (typeof Object.assign != 'function') {
  // Must be writable: true, enumerable: false, configurable: true
  Object.defineProperty(Object, "assign", {
    value: function assign(target, varArgs) { // .length of function is 2
      'use strict';
      if (target == null) { // TypeError if undefined or null
        throw new TypeError('Cannot convert undefined or null to object');
      }

      var to = Object(target);

      for (var index = 1; index < arguments.length; index++) {
        var nextSource = arguments[index];

        if (nextSource != null) { // Skip over if undefined or null
          for (var nextKey in nextSource) {
            // Avoid bugs when hasOwnProperty is shadowed
            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
              to[nextKey] = nextSource[nextKey];
            }
          }
        }
      }
      return to;
    },
    writable: true,
    configurable: true
  });
}

2
Ich habe versucht, "lib": ["es2015", "es2017", "dom"], aber ich erhalte immer noch Eigenschaft 'Werte' existiert nicht vom Typ 'ObjectConstructor'. Ich denke, es ist nicht in der Spezifikation
— Nikos


Wenn WebStorm Ihnen zufällig einen Fehler gibt, müssen Sie das Javascript.next-Plugin hier installieren: plugins.jetbrains.com/plugin/…
— Nicolas Boulet-Lavoie

Das Ändern von tsconfig.json ist die einzige Problemumgehung, die für mich funktioniert. dh hinzufügen"lib": [ "es2015", "es2017", "dom" ]
— Danny Sofftie

2
@AQuirky Die TypeScriptTargetOption ändert die Zielversion von EmcaScript (~ den formalen Javascript-Namen). Zu ES2015Ihrer Information : ist nicht kompatibel mit IE11 (falls Sie es unterstützen müssen). Sie können immer noch gesetzt TypeScriptTargetzu , ES5während auch Einstellung TypeScriptLibauf DOM, ES2015die gleiche Update auch zu erreichen , während mit IE11 kompatibel bleibt (aber wenn Sie IE nicht unterstützen müssen, dann nur gesetzt TypeScriptTarget zu ES2015).
— Rico Kahler

128

Dies wird dadurch verursacht, dass Sie eine ECMAScript 6-Funktion verwenden und auf ECMAScript 5 oder 3 abzielen. Die einfachste Lösung besteht darin, das richtige Ziel festzulegen, z. B. wenn Sie Grunt verwenden:

options: {
    target: 'es6'
}

Ändern Sie die entsprechende Eigenschaftsregisterkarte in Visual Studio oder manuell, indem Sie Ihre .csproj-Datei bearbeiten, das TypeScriptTarget-Element suchen und zu ES6 wechseln. Beispiel:

<TypeScriptTarget>ES6</TypeScriptTarget>

Wenn Sie auf ES5 abzielen müssen, fügen Sie Ihrem TypeScript-Code lediglich Folgendes hinzu

declare interface ObjectConstructor {
    assign(target: any, ...sources: any[]): any;
}

Dadurch wird die zusätzliche Methode zusammengeführt und das Problem gelöst. Weitere Details hier . Abhängig von den Kompatibilitätsanforderungen Ihres Browsers benötigen Sie möglicherweise eine Polyfüllung - zum Beispiel diese von MDN :

if (typeof Object.assign != 'function') {
  (function () {
    Object.assign = function (target) {
      'use strict';
      if (target === undefined || target === null) {
        throw new TypeError('Cannot convert undefined or null to object');
      }

      var output = Object(target);
      for (var index = 1; index < arguments.length; index++) {
        var source = arguments[index];
        if (source !== undefined && source !== null) {
          for (var nextKey in source) {
            if (source.hasOwnProperty(nextKey)) {
              output[nextKey] = source[nextKey];
            }
          }
        }
      }
      return output;
    };
  })();
}

5
@JoeKeene Diese Antwort löst das Problem nicht optimal wie bei TS 2.0+. Wenn Sie auf ES5 abzielen, sollten Sie die --lib es2015Compileroption verwenden. Mein Problem mit dem obigen Ansatz ist, dass Sie, wenn Sie declaredie Object.assignFunktion anstelle der integrierten Deklaration verwenden, keine ordnungsgemäße Eingabe und Dokumentation erhalten. Sie haben die --libOption hinzugefügt, damit Sie Schnittstellen, die bereits Teil des Standards sind, nicht erneut deklarieren müssen.
— Rico Kahler

Damit dies funktioniert, musste ich die Schnittstellendeklaration zu einer typings ( .d.ts) - Datei und nicht zu einer typescript ( ) - Datei hinzufügen .ts.
— Mike Chamberlain

@uksz Vielleicht, da dies nicht hacky ist, sollte es akzeptiert werden?
— Jason

Ich wechselte "target": "es5",zu "target": "es6",in tsconfig.json. und es funktionierte (y)
— theapache64

1
Denn Object.valueses muss sein "target": "es2017", da dies das Top-Suchergebnis für den gleichen Fehlercode ist.
— NobleUplift

3

Sie können den Spread-Operator wie in ES6 verwenden

const obj = {...this.success,...success.json()};


1

Ich habe Typisierungen hinzugefügt:

typings install dt~es6-shim --global --save

1
Sieht aus wie die gleichen Eingaben, die ich geantwortet habe? Oder fehlt mir etwas?
— Sergejs

0

Warum nicht den Spread-Operator verwenden?

return {this.success, ...success.json() || {}};


-1

Ich weiß, das ist lange her, aber hier ist eine einfache Lösung

(Object as any).assign(this.success, success.json())
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.