'Atama' özelliği 'ObjectConstructor' türünde mevcut değil


130

İşlevini kullandığım uygulamamda TypeScript kullanıyorum:

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

Ancak, derleme sırasında aşağıdaki hatayı alıyorum:

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

Bu hatadan nasıl kurtulabileceğime dair bir fikriniz var mı?


lütfen kabul edilen yanıtı değiştirmeyi düşünün - o zamandan beri daha fazla olumlu oyla çok daha iyi yanıtlar yayınlandı.
mindplay.dk

Yanıtlar:


130

Tür onayını şu şekilde kullanabilirsiniz :

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

30
Vay canına, süper hacky görünüyor .. (<any> Object) ne yaptığını açıklayabilir misiniz?
uksz

Pekala, Object'in herhangi bir türe sahip olduğunu beyan ediyorum.
uksz

31
Bu bir çözüm gibi görünse de, gerçekten tek bir çözüm olarak görülmemelidir. Daha sonra basitçe belirsizlik eklemek ve transpiler hatalarını gizlemek (ki bunu yapar), onları gerçekten düzeltmek ve konsoldan yararlı geri bildirimler almak çok daha iyidir.
Dmitry Parzhitsky

6
Bu sadece sorunu yayınlamak ve saklamaktır. Potansiyel olarak belirli tarayıcılarda vb.
Çoklu dolgu

3
Buraya bakan herkese, tsconfigbundan daha iyi bir çözüm olan sizin için ne ekleneceğini açıkladığı yerde biraz daha aşağı kaydırmasını tavsiye ederim .
mesqueeb

175

Yapılandır:

VS kodunu kullanıyorsanız (veya bir tsconfig.jsondosya görüyorsanız ):

libÖzelliği kendinize eklemelisiniz, tsconfig.jsonardından editörünüz paketlenmiş daktilo türü tanımlarını kullanacak ve ayrıca size bilgi verecektir.

Sadece VS kodunu "lib": ["esnext", "dom"]ekleyin tsconfig.jsonve VS Kodunu yeniden başlatın

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

Buradaki tüm tsconfig.jsonseçenekleri görün .

Visual Studio veya MSBuild kullanıyorsanız şu etiketi ekleyin:

<TypeScriptLib>esnext, dom</TypeScriptLib>

Tüm MSBuild typecript derleyici seçeneklerine ve kullanımına buradan bakın .


İşini kontrol et:

Eğer tipleri dahili ve yeniden senin editörü kullanmak projenizi yapılandırdıysanız, ardından çıkan tipi yerine türü varlığının bu gibi görünecektir anykullandığınızda Object.assign:

kod örneği 1


Çoklu dolgular ve daha eski tarayıcı uyumluluğu hakkında not:

Not Eğer ES5 veya daha düşük transpiling ve IE11 hedefliyorsanız typescript derleyici sizin için polyfills içermez, çünkü polyfills dahil etmek gerektiğini.

Polyfills'i eklemek istiyorsanız (ki yapmalısınız) o zaman core-js'in polyfill'lerini kullanmanızı tavsiye ederim.

npm install --save core-js

veya

yarn add core-js

Ardından, uygulamanızdaki giriş noktasında (ör. /src/index.ts) İçe aktarmayı core-jsdosyanın en üstüne ekleyin :

import 'core-js';

Bir paket yöneticisi kullanmıyorsanız, MDN'den alınan aşağıdaki çoklu dolguyu , kullanımınızdan önce çalışan kodunuzda bir yere yapıştırabilirsiniz 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
"Lib" denedim: ["es2015", "es2017", "dom"] ama yine de Özellik 'değerleri' alıyorum 'ObjectConstructor' türünde mevcut değil. , Sanırım şartnamede değil
Nikos

1
@Nikos, kod mu yeniden başlattınız mı? Object.valuesşartnamede. ve typcript bunun için yazımlara sahiptir .
Rico Kahler

Şans eseri WebStorm size bir hata verirse, Javascript.next eklentisini buraya yüklemeniz gerekir: plugins.jetbrains.com/plugin/…
Nicolas Boulet-Lavoie

Tsconfig.json'ı değiştirmek benim için çalışan tek geçici çözümdür. yani ekleyerek"lib": [ "es2015", "es2017", "dom" ]
Danny Sofftie

2
@AQuirky Bu TypeScriptTargetseçenek, EmcaScript'in hedef sürümünü (~ resmi javascript adı) değiştirir. Bilginize: ES2015IE11 ile uyumlu değildir (desteklemeniz gerektiğinde). Hala ayarlayabilirsiniz TypeScriptTargetiçin ES5de ayarlarken TypeScriptLibiçin DOM, ES2015de IE11 ile uyumlu kalırken aynı düzeltmeyi elde etmek (ama IE desteklemek yoksa, o zaman sadece set TypeScriptTarget için ES2015).
Rico Kahler

128

Bunun nedeni bir ECMAScript 6 özelliği kullanmanız ve ECMAScript 5 veya 3'ü hedeflemenizdir. En kolay düzeltme, örneğin Grunt kullanıyorsanız, doğru hedefi belirlemektir:

options: {
    target: 'es6'
}

Visual Studio'da ilgili özellik sekmesini değiştirin veya .csproj dosyanızı manuel olarak düzenleyerek ve TypeScriptTarget öğesini bularak ve ES6 olarak değiştirerek, örneğin:

<TypeScriptTarget>ES6</TypeScriptTarget>

ES5'i hedeflemeniz gerekiyorsa, yalnızca aşağıdakileri TypeScript kodunuza ekleyin

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

Bu, sorunu çözmek için ekstra yöntemi birleştirir. Daha fazla ayrıntı burada . Yine de, tarayıcı uyumluluk gereksinimlerinize bağlı olarak bir polyfill'e ihtiyacınız olabilir - örneğin bu MDN'den :

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 Bu cevap sorunu TS 2.0+ gibi en iyi şekilde çözmez. ES5'i hedefliyorsanız, --lib es2015derleyici seçeneğini kullanmalısınız . Yukarıdaki yaklaşımla Sorunum eğer o kullanmak yerine işlevi yerleşik beyanında o zaman doğru yazma ve belgelere alamayacak. Zaten standardın parçası olan arayüzleri yeniden bildirmek zorunda kalmamanız için seçeneği eklediler . declareObject.assign--lib
Rico Kahler

Bunun çalışması için arabirim bildirimini bir typings ( .d.ts) dosyası yerine bir typings ( ) dosyasına eklemem gerekiyordu .ts.
Mike Chamberlain

@uksz Belki de bu hacky olmadığı için kabul edilmeli?
Jason

Değiştim "target": "es5",için "target": "es6",de tsconfig.json. ve işe yaradı (y)
theapache64

1
Çünkü Object.values, "target": "es2017"aynı hata kodu için en üstteki arama sonucu bu olduğundan olmalıdır .
NobleUplift

3

Yayılma operatörünü ES6'daki gibi kullanabilirsiniz

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


1

Yazılar ekledim:

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

1
Yanıtladığım yazılarla aynı mı görünüyor? Yoksa bir şey mi kaçırıyorum?
Sergejs

0

Yayma operatörünü neden kullanmıyorsunuz?

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


-1

Bunun uzun olduğunu biliyorum ama işte kolay bir düzeltme

(Object as any).assign(this.success, success.json())
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.