У меня есть файлы TypeScript:
MyClass.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();
Это дает мне ошибки при попытке использовать new
Модуль «MyClass» преобразуется в немодульную сущность и не может быть импортирован с помощью этой конструкции.
и при попытке позвонить fn()
Невозможно вызвать выражение, тип которого не имеет сигнатуры вызова.
Что дает?
typescript
ecmascript-6
es6-modules
Райан Кавано
источник
источник
javascript
в качестве основного тега и оставитьecmascript-6
, потому что здесь основной тегtypescript
. Вопрос ошибочно предполагает, чтоexport =
(функция TS) может быть связана сimport ... from
, в то время как она должна быть связана сimport =
. Это в основном импорт / экспорт модуля ES6 по сравнению с CJS / AMD.Ответы:
Почему не работает
import * as MC from './MyClass';
Это
import
синтаксис в стиле ES6 / ES2015 . Точное значение этого слова: «Возьмите загруженный объект пространства имен модуля./MyClass
и используйте его локально какMC
». Примечательно, что « объект пространства имен модуля » состоит только из простого объекта со свойствами. Объект модуля ES6 не может быть вызван как функция или сnew
.Для того, чтобы сказать это снова: ES6 объект модуля пространства имен не может быть вызван в качестве функции или с
new
.Вещь, которую вы
import
используете* as X
из модуля, определяется только как имеющая свойства. В пониженном уровне CommonJS это может не соблюдаться полностью, но TypeScript сообщает вам, каково поведение, определенное стандартом.Что работает?
Чтобы использовать этот модуль, вам нужно будет использовать синтаксис импорта в стиле CommonJS:
import MC = require('./MyClass');
Если вы управляете обоими модулями, вы можете использовать
export default
вместо них:MyClass.ts
export default class MyClass { constructor() { } }
MyConsumer.ts
import MC from './MyClass';
Мне грустно об этом; Правила глупы.
Было бы неплохо использовать синтаксис импорта ES6, но теперь я должен это сделать
import MC = require('./MyClass');
? Наступил такой 2013 год! Ламе! Но горе - нормальная часть программирования. Перейдите к пятому этапу модели Кюблер-Росс: Принятие.TypeScript здесь говорит вам, что это не работает, потому что это не работает. Есть хаки (добавление
namespace
объявления вMyClass
- популярный способ притвориться, что это работает), и они могут работать сегодня в вашем конкретном сборщике модулей с понижением уровня (например, свертке), но это иллюзия. В мире пока нет реализаций модулей ES6, но так будет не всегда.Представьте себя в будущем, пытаясь работать на аккуратной собственной реализации модуля ES6 и обнаруживая, что вы настроили себя на серьезную неудачу, пытаясь использовать синтаксис ES6 для выполнения чего-то, чего ES6 явно не делает .
Я хочу воспользоваться моим нестандартным загрузчиком модулей
Возможно, у вас есть загрузчик модулей, который «услужливо» создает
default
экспорт, когда его нет. Я имею в виду, что люди создают стандарты по какой-то причине, но игнорировать стандарты иногда весело, и мы можем подумать, что это круто.Измените MyConsumer.ts на:
import A from './a';
И укажите
allowSyntheticDefaultImports
командную строку илиtsconfig.json
параметр.Обратите внимание, что это
allowSyntheticDefaultImports
никак не меняет поведение вашего кода во время выполнения. Это просто флаг, который сообщает TypeScript, что ваш загрузчик модуля создаетdefault
экспорт, когда его нет. Это не заставит ваш код работать в nodejs волшебным образом, если этого не было раньше.источник
export = MyClass
? Мой единственный вариант - установить мой модульcommonjs
и продолжать делать мир хуже, не используя современные ES?--esModuleInterop
, говорится: «Мы настоятельно рекомендуем применять его как к новым, так и к существующим проектам». На мой взгляд, этот ответ (и запись / политика в FAQ поDefinitelyTyped
этим ссылкам здесь) следует изменить, чтобы отразить новую позицию.TypeScript 2.7 представляет поддержку путем создания новых вспомогательных методов: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#support-for-import-d-from-cjs-form- commonjs-modules-with --- esmoduleinterop
Итак, в tsconfig.json добавьте эти две настройки:
{ // 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 }
И теперь вы можете использовать:
import MyClass from './MyClass';
источник
esModuleInterop
я использовалresolveJsonModule
ваше другое предложение об использовании,allowSyntheticDefaultImports
и это сработало для меня.Добавьте сюда мои 2 цента, если у кого-то еще есть эта проблема.
Мой способ решения проблемы без изменения
tsconfig.json
(что может быть проблематичным в некоторых проектах), я просто отключил правило для oneline.import MC = require('./MyClass'); // tslint:disable-line
источник
Я получил эту ошибку при попытке включить пакет противодействия npm в свой проект.
Когда я попробовал принятое выше решение, у меня возникло исключение:
В итоге это сработало:
import debounce from 'debounce'
источник