La propiedad 'asignar' no existe en el tipo 'ObjectConstructor'


130

Estoy usando TypeScript en mi aplicación, donde uso la función:

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

Sin embargo, durante la compilación, recibo el siguiente error:

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

¿Tienes alguna idea de cómo puedo deshacerme de este error?


considere cambiar la respuesta aceptada: desde entonces se han publicado respuestas mucho mejores con más votos a favor.
— mindplay.dk

Respuestas:


129

Puede usar la aserción de tipo , así:

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

30
Wow, parece súper hacky .. ¿Podría explicar qué hace (<any> Object)?
— uksz

Muy bien, veo que estoy declarando que Object tiene el tipo any.
— uksz

31
Aunque esto parece una solución, realmente no debe tratarse como tal. En lugar de simplemente agregar ambigüedad y ocultar los errores del transpilador (lo cual hace), es mucho mejor corregirlos y obtener comentarios útiles de la consola.
— Dmitry Parzhitsky

66
Esto es solo lanzar y ocultar el problema. Es posible que necesite usar polyfills en navegadores específicos, etc. Esto provocará errores en algunos navegadores
— Tom McKearney

3
Aconsejaría a cualquiera que busque aquí desplazarse un poco más hacia abajo, donde explica qué agregar a usted, tsconfigque es una mejor solución que esta.
— mesqueeb

175

Configurar:

Si está utilizando el código VS (o si ve un tsconfig.jsonarchivo):

Debe agregar la libpropiedad a su tsconfig.jsony luego su editor usará las definiciones de tipo de mecanografiado incluidas y también le dará inteligencia.

Simplemente agregue el "lib": ["esnext", "dom"]a su tsconfig.jsony reinicie VS Code

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

Ver todas las tsconfig.jsonopciones aquí .

Si está utilizando Visual Studio o MSBuild, incluya esta etiqueta:

<TypeScriptLib>esnext, dom</TypeScriptLib>

Vea todas las opciones y el uso del compilador de mecanografía MSBuild aquí .


Revisa tu trabajo:

Si configuró su proyecto para usar los tipos incorporados y reinició su editor, entonces su tipo resultante se verá así en lugar del tipo anycuando usa Object.assign:

ejemplo de código 1


Nota sobre polyfills y compatibilidad con navegadores anteriores:

Tenga en cuenta que si está transfiriendo a ES5 o inferior y está apuntando a IE11, deberá incluir polyfills porque el compilador de mecanografiado no incluirá los polyfills por usted.

Si desea incluir los polyfills (que debería), le recomendaría usar polyfills de core-js.

npm install --save core-js

o

yarn add core-js

Luego, en el punto de entrada de su aplicación (por ejemplo /src/index.ts), agregue la importación core-jsen la parte superior del archivo:

import 'core-js';

Si no está utilizando un administrador de paquetes, puede pegar el siguiente polyfill tomado de MDN en algún lugar de su código que se ejecute antes de usarlo 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
Intenté "lib": ["es2015", "es2017", "dom"] pero todavía obtengo 'Valores' de propiedad no existe en el tipo 'ObjectConstructor'. , Supongo que no está en la especificación
— Nikos


Si por casualidad WebStorm le da un error, necesita instalar el complemento Javascript.next aquí: plugins.jetbrains.com/plugin/…
— Nicolas Boulet-Lavoie

Modificar tsconfig.json es la única solución que me funciona. es decir, agregar"lib": [ "es2015", "es2017", "dom" ]
— Danny Sofftie

2
@AQuirky La TypeScriptTargetopción cambia la versión de destino de EmcaScript (~ el nombre formal de JavaScript). FYI: ES2015no es compatible con IE11 (en caso de que tenga que soportarlo). Todavía se puede fijar TypeScriptTargeta ES5la vez que establecer TypeScriptLibpara DOM, ES2015lograr el mismo arreglo al mismo tiempo que mantiene la compatibilidad con IE11 (pero si usted no tiene que soportar IE, a continuación, acaba de establecer TypeScriptTarget a ES2015).
— Rico Kahler

128

Esto se debe a que usa una función ECMAScript 6 y apunta a ECMAScript 5 o 3. La solución más fácil es establecer el objetivo correcto, por ejemplo, si está usando Grunt:

options: {
    target: 'es6'
}

de cambiar la pestaña de propiedad relevante en Visual Studio, o manualmente editando su archivo .csproj y encontrando el elemento TypeScriptTarget y cambiando a ES6, por ejemplo:

<TypeScriptTarget>ES6</TypeScriptTarget>

Si necesita apuntar a ES5, simplemente agregue lo siguiente a su código TypeScript

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

Eso combina el método adicional en la resolución del problema. Más detalles aquí . Sin embargo, es posible que necesite un polyfill, según los requisitos de compatibilidad de su navegador , por ejemplo, este de 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;
    };
  })();
}

55
@JoeKeene Esta respuesta no resuelve el problema de la mejor manera que para TS 2.0+. Si está apuntando a ES5, entonces debe usar la --lib es2015opción del compilador. Mi problema con el enfoque anterior es que si utiliza declarela Object.assignfunción en lugar de utilizar la declaración integrada, no obtendrá la escritura y la documentación adecuadas. Agregaron la --libopción para que no tenga que volver a declarar interfaces que ya son parte del estándar.
— Rico Kahler

Para que esto funcione, tuve que agregar la declaración de interfaz a un .d.tsarchivo typings ( ), en lugar de un .tsarchivo mecanografiado ( ).
— Mike Chamberlain

@uksz ¿Tal vez como esto no es hacky, debería ser aceptado?
— Jason

Me cambié "target": "es5",a "target": "es6",adentro tsconfig.json. y funcionó (y)
— theapache64

1
Para Object.values, debe ser "target": "es2017", ya que este es el resultado de búsqueda superior para el mismo código de error.
— NobleUplift

3

Puede usar el operador de propagación como en ES6

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


1

He agregado tipings:

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

1
Parece el mismo tipo de respuestas que he respondido? ¿O me estoy perdiendo algo?
— Sergejs

0

¿Por qué no usar el operador de propagación?

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


-1

Sé que esto ha sido largo pero aquí hay una solución fácil

(Object as any).assign(this.success, success.json())
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.