"… Modül olmayan bir varlığa çözümlenir ve bu yapı kullanılarak içe aktarılamaz" ne anlama gelir?


93

Bazı TypeScript dosyalarım var:

Sınıfım.ts

class MyClass {
  constructor() {
  }
}
export = MyClass;

MyFunc.ts

function fn() { return 0; }
export = fn;

MyConsumer.ts

import * as MC from './MyClass';
import * as fn from './MyFunc';
fn();

Bu, kullanmaya çalışırken bana hatalar veriyor new

Modül "Sınıfım", modül olmayan bir varlığa çözümlenir ve bu yapı kullanılarak içe aktarılamaz.

ve aramaya çalışırken fn()

Türünde çağrı imzası olmayan bir ifade çağırılamaz.

Ne oluyor?


2
Cevabınızı paylaştığınız için teşekkürler. Buradaki birincil etiket olduğu için birincil etiket javascriptolarak kaldırıp ayrılmanızı öneririm . Soru yanlış olduğunu varsayar (TS özelliği) ile eşleştirilmiş olabilir iken, bu eşleştirilmiş olmalıdır . Temelde CJS / AMD'ye karşı ES6 modülü içe / dışa aktarımıdır. ecmascript-6typescriptexport =import ... fromimport =
Estus Flask

Yanıtlar:


158

Neden çalışmıyor

import * as MC from './MyClass';

Bu, ES6 / ES2015 tarzı importsözdizimidir. Bunun tam anlamı " Yüklenen modül ad alanı nesnesini al ./MyClassve yerel olarak kullan MC" şeklindedir. Özellikle, "modül ad alanı nesnesi " yalnızca özelliklere sahip düz bir nesneden oluşur. Bir ES6 modülü nesnesi bir işlev olarak veya ile çağrılamaz new.

Tekrar söylemek gerekirse: Bir ES6 modülü ad alanı nesnesi bir işlev olarak veya ile çağrılamaz new.

Bir modülden importkullandığınız şey * as Xsadece özelliklere sahip olacak şekilde tanımlanmıştır. Düşük seviyeli CommonJS'de buna tam olarak uyulmayabilir, ancak TypeScript size standart tarafından tanımlanan davranışın ne olduğunu söylüyor.

Ne işe yarar?

Bu modülü kullanmak için CommonJS tarzı içe aktarma sözdizimini kullanmanız gerekir:

import MC = require('./MyClass');

Her iki modülü de kontrol ediyorsanız, export defaultbunun yerine şunu kullanabilirsiniz :

Sınıfım.ts

export default class MyClass {
  constructor() {
  }
}

MyConsumer.ts

import MC from './MyClass';

Üzgünüm Bu; Kurallar Aptaldır.

ES6 içe aktarma sözdizimini kullanmak güzel olurdu, ama şimdi bunu yapmak zorunda import MC = require('./MyClass');mıyım? Çok 2013! Topal! Ancak keder, programlamanın normal bir parçasıdır. Lütfen Kübler-Ross modelinde beşinci aşamaya geçin: Kabul.

Buradaki TypeScript size bunun işe yaramadığını söylüyor çünkü işe yaramıyor. Orada (bir ekleme kesmek vardır namespaceiçin deklarasyon MyClassbu eserler taklit popüler bir yoldur) ve bunlar olabilir (örn toplaması) belirli downleveling modülü paketleyici bugün çalışır, ancak bu yanıltıcıdır. Henüz vahşi ortamda ES6 modülü uygulaması yok, ancak bu sonsuza kadar doğru olmayacak.

Gelecekteki halinizi hayal edin, yeni bir yerel ES6 modülü uygulamasında çalışmaya çalışın ve ES6'nın açıkça yapmadığı bir şeyi yapmak için ES6 sözdizimini kullanmaya çalışarak kendinizi büyük bir başarısızlığa hazırladığınızı görün .

Standart olmayan modül yükleyicimden yararlanmak istiyorum

Belki de defaultmevcut olmadığında dışa aktarımları "faydalı bir şekilde" oluşturan bir modül yükleyiciniz vardır. Demek istediğim, insanlar bir nedenden ötürü standartları belirler, ancak standartları göz ardı etmek bazen eğlencelidir ve bunun yapılacak harika bir şey olduğunu düşünebiliriz.

MyConsumer.ts'i şu şekilde değiştirin :

import A from './a';

Ve allowSyntheticDefaultImportskomut satırını veya tsconfig.jsonseçeneği belirtin .

allowSyntheticDefaultImportsKodunuzun çalışma zamanı davranışını hiç değiştirmediğini unutmayın . Bu, TypeScript'e modül yükleyicinizin defaulthiçbiri olmadığında dışa aktarmalar oluşturduğunu söyleyen bir bayraktır . Daha önce yapmadığı halde kodunuzun nodej'lerde çalışmasını sihirli bir şekilde yapmaz.


Commonjs stili bir commonjs hedefi gerektirmiyor mu? Es6 / es2015'i hedeflerken bunun işe yaramasını sağlamanın bir yolu var mı?
Steve Buzonas

ES6'da çalışmadığı için ES6'yı hedef alarak çalışmasını sağlayamazsınız ...
Ryan Cavanaugh

ES2015 modüllerini hedefliyorsam, sahip olan bir CommonJS modülüne başvurmanın bir yolu olmadığını anlamakta haklı mıyım export = MyClass? Tek seçeneğim modülümü commonjsmodern ES kullanmayarak dünyayı daha kötü bir yer haline getirmeye devam etmek mi?
Micah Zoltu

6
In 2.7 sürüm notları , under --esModuleInterop, bu "Biz çok yeni ve mevcut projelere bunu hem uygulayarak tavsiye" diyor. Bence, bu yanıt (ve SSS giriş / politika içinde DefinitelyTypedburada bu bağlantılar) yeni duruşunu yansıtacak şekilde değiştirilmelidir.
Alec Mev

1
Yani çok şımarık.
jmealy

25

TypeScript 2.7, yeni yardımcı yöntemler yayarak destek sunar: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#support-for-import-d-from-cjs-form- commonjs-modülleri-ile --- esmoduleinterop

Yani tsconfig.json'da şu iki ayarı ekleyin:

{
    // Enable support for importing CommonJS modules targeting es6 modules
    "esModuleInterop": true,

    // When using above interop will get missing default export error from type check since
    // modules use "export =" instead of "export default", enable this to ignore errors.
    "allowSyntheticDefaultImports": true
}

Ve şimdi kullanabilirsiniz:

import MyClass from './MyClass';

Bunun yerine kullanmanın esModuleInteropkullandığım resolveJsonModulekullanmanın diğer öneri tarafı boyunca allowSyntheticDefaultImportsve bu benim için çalıştı.
Edgar Quintero

6

Buraya 2 sentimi eklemek, başka birinin bu sorunu yaşaması durumunda.

Değiştirmeden soruna çalışma tarzım tsconfig.json(bazı projelerde sorunlu olabilir), ben sadece OneLine için kuralı devre dışı bırakma ile gittim.

import MC = require('./MyClass'); // tslint:disable-line


5

Projeme bir npm geri alma paketi eklemeye çalışırken bu hatayı aldım.

Yukarıda kabul edilen çözümü denediğimde bir istisna yaşadım:

ECMAScript modülleri hedeflenirken içe aktarma ataması kullanılamaz. "Mod" dan ns olarak "içe aktar *", "mod" dan "içe aktar {a}", "mod" dan "d içe aktar" veya bunun yerine başka bir modül biçimini kullanmayı düşünün.

Bu işe yaradı:

import debounce from 'debounce' 
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.