Typescript: Ошибка «Невозможно скомпилировать пространства имен» с --isolatedModules и без пространств имен

Созданный на 17 апр. 2017  ·  52Комментарии  ·  Источник: microsoft/TypeScript

Версия TypeScript: nightly (2.3.0-dev.20170417)

Код

function f() {}

Ожидаемое поведение:

Нет ошибки или сообщение об ошибке о немодульном файле в проекте --isolatedModules .

Фактическое поведение:

src/a.ts(1,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided.

Это происходит потому, что мы в program.ts verifyCompilerOptions ищем любой исходный файл, который не является объявлением внешнего модуля, и терпим неудачу при первом из них, каким бы он ни был.
Сообщение об ошибке должно быть обновлено, чтобы отразить реальную причину, по которой мы выдаем эту ошибку, без упоминания пространств имен.
В качестве альтернативы, мы могли бы просто разрешить файлы без импорта и фактически искать пространство имен перед добавлением этой ошибки.

Bug Error Messages help wanted

Самый полезный комментарий

A global file cannot be compiled using '--isolatedModules'. Ensure your file contains imports, exports, or an 'export {}' statement.

Все 52 Комментарий

Сообщение об ошибке должно быть более четким. вместо namespaces он может сказать non-module . Рекомендации @DanielRosenwasser ?

В этой ситуации не должно быть сообщения об ошибке. Параметр --isolatedModules должен просто полностью отключить внутреннюю модульную систему, если tsc все еще выдает ошибку, значит, параметр не выполнил свою работу.

В # 15839 я намеревался изменить поведение проверки, но позже понял, что эта проверка просто бессмысленна и идеальным решением является ее удаление.
Typescript всегда разрешал использование пространства имен внутри внешнего модуля с --isolatedModules on:

export function something() {} // export found, so this module is considered 'external'
namespace ns {} // namespace is still valid in an external module

Таким образом, проверка ничего не делает в том (на первый взгляд недействительном) случае, когда она должна пожаловаться. Так зачем жаловаться, когда программист даже не использует какое-либо пространство имен, не делая ничего плохого?

@wilonth Причина этой проблемы в том, что сообщение об ошибке неверное: пространства имен прекрасно подходят, если они являются частью модуля (es6), но любой файл, не являющийся модулем, должен быть ошибкой.

@ andy-ms Я пытался указать, что весь код для проверки этой ошибки просто бессмыслен, и мы должны просто удалить его, а не усложнять код еще больше.
Я хочу сказать, что когда --isolatedModules включен, каждый файл следует рассматривать как внешний (ES6) модуль, точка. В этом смысле использование пространств имен должно быть законным, потому что сейчас совершенно законно использовать пространства имен внутри модулей ES6 (с включенным --isolatedModules ).

Я хочу сказать, что когда --isolatedModules включен, каждый файл следует рассматривать как внешний (ES6) модуль, точка.

Семантика здесь такова, что модуль - это файл с как минимум одним импортом или экспортом верхнего уровня. не имеет значения, как вы вызываете компилятор.

@mhegazy Да, и это правило как раз и является корнем --isolatedModules отклоняет файл.
Теперь нам не следует изменять правило, потому что это, вероятно, нарушит многие вещи, но мы можем очень легко решить текущую проблему, просто удалив это сообщение об ошибке.
Представим, что сообщение об ошибке «не удается скомпилировать пространства имен» удаляется, что может пойти не так? А как насчет кодовой базы, которая использует внутренний модуль, например, сам компилятор Typescript? При включении --isolatedModules компилируется ли он в мусорный код и сбивает пользователя с толку? Нет, не будет, будет много сообщений об ошибках Typescript о неопределенных символах, потому что --isolatedModules разорвал связи между файлами, что довольно очевидно для понимания.
Можете ли вы найти ЛЮБЫЕ недостатки при удалении этого сообщения об ошибке? Я не мог. Почему бы нам не выбрать самое простое решение, которое не требует работы (просто убирает линии) и не имеет недостатков?

При включении --isolatedModules он будет компилироваться в мусорный код и запутать пользователя? Нет не будет

Да, это будет.

Смысл флага --isolatedModules состоит в том, чтобы проверить, что программа может быть успешно скомпилирована посредством однофайловой транспиляции.

Кодовая база TypeScript не может быть успешно скомпилирована посредством однофайловой транспиляции. Повсюду есть такой код:

file1

namespace ts {
  export var x = 10;
}

файл2

namespace ts {
  var y = x; // transpiles to ts.x during whole-program compilation
}

Если бы мы однофайловой перекомпилировали file2, он бы сломался.

Моя проблема, я провалил тестирование. Настоящим я отказываюсь от своего предложения. Спасибо @RyanCavanaugh за напоминание.

Таким образом, решение должно быть следующим: обнаружение реального использования пространства имен перед выдачей этого сообщения об ошибке (т.е. «альтернативное» решение, предложенное @andy-ms). Мы не можем просто изменить текст на что-то другое, потому что сообщение об ошибке в этом случае совершенно неверное.
Я хочу устроить пиар, но можно ли мне доверять здесь после того, как извергнул всю эту чушь?

A global file cannot be compiled using '--isolatedModules'. Ensure your file contains imports, exports, or an 'export {}' statement.

Если бы мы однофайловой перекомпилировали file2, он бы сломался.

Извините за некромантию, но, конечно же, при нацеливании на модули это должно приводить к сбою с чем-то вроде 'x' is not defined ? Мне этот случай ничем не отличается от тривиального:

file1

var x = 10;

файл2

var y = x;

Что также работает при объединении / глобальной оценке, а не с модулями; ничего общего с namespaces .

По сути, почему машинописный текст пытается угадать, что файлы без import или export не являются модулями, когда он уже должен знать из параметра компилятора module ? Например, Typescript сам компилируется без установки module , поэтому он использует значение по умолчанию none , поэтому компилятор может предполагать конкатенацию / глобальную оценку.

При использовании --module <something> и неимпортированных деклараций из других файлов (включая сами пространства имен) машинописный код уже завершится ошибкой со словом «не определено» до --isolatedModules , и то же самое после с export {} обходной путь, так что это не похоже на нарушение совместимости для устранения этой догадки - я что-то упустил?

Я заметил, что по какой-то причине вы все еще можете использовать import / export с --module none --isolatedModules , что довольно сбивает с толку, возможно, ошибка?

@DanielRosenwasser как конечный пользователь: что означает «глобальный файл»? Хотя мне нравится руководство. Возможно, это больше похоже на «Файлы без каких-либо операторов импорта или экспорта не являются модулями и не могут быть скомпилированы с помощью '--isolatedModules'. Добавьте оператор 'export {}', если этот файл оценивается только на предмет его побочных эффектов». - хотя язык там не очень похож на сообщение об ошибке.

Я вижу ту же ошибку для простого проекта js. Я только что создал образец проекта js, ниже представлены файлы пакета и сценария. Как я могу решить эту проблему?

Package.json
{
"plnkr": {
"время выполнения": "система"
}
}

lib / script.js
//
//Блэк Джек
// Дирадж Кумар
//

let card1 = "Туз пик",
card2 = «десятка червей»;

console.log («Добро пожаловать в блэкджек!»);

console.log ("Вам раздали:");
conosle.log ("" + card1);
console.log ("" + card2);

Есть обновления по этому поводу?

Я часто делаю это в небольших тестах.

describe('jest', () => {
  it('finds this test', () => {
    expect(true).toBeTruthy();
  });

  it('parses this typescript', () => {
    const actual: number = 0;
    const expected: number = 0;
    expect(actual).toEqual(expected);
  });
});

export {
  // Use an empty export to please Babel's single file emit.
  // https://github.com/Microsoft/TypeScript/issues/15230
}

Мне действительно нужна опция, которая заставит TypeScript рассматривать каждый файл .ts как модуль ES6, независимо от того, содержит ли он операторы импорта / экспорта или нет. Первоначально я предполагал, что этим вариантом является вариант --isolatedModules , но он вызывает чрезвычайно запутанную ошибку для файлов без импорта / экспорта. (Я до сих пор не понимаю, что означает сообщение об ошибке под пространствами имен. Я не думаю, что использую эту функцию.) Причина, по которой мне нужен этот параметр, заключается в том, что у меня было несколько проблем, не обнаруженных TypeScript, потому что я случайно указал переменная верхнего уровня из одного файла .ts в другом (оба не имеют операторов импорта / экспорта, поэтому TypeScript не рассматривал их как модули ES6), несмотря на использование node / parcel / webpack, где файлы не могут ссылаться друг на друга такие неэкспортированные переменные.

Я оказался здесь, пытаясь исправить какое-то раздражение. Комментарии ниже предназначены только для того, чтобы помочь другим пользователям VS Code, которые ищут эту ошибку с помощью create-react-app и TypeScript.

При настройке прокси с помощью create-react-app 2.x и TypeScript вы добавляете файл с именем setupProxy.js с таким кодом:

const proxy = require('http-proxy-middleware');
module.exports = function(app) { /* ... */ };

react-scripts читает этот файл вне процесса транспиляции ts, поэтому он должен быть простым js.

Это работает точно так, как описано в документации , но имеет неприятный побочный эффект.

tsconfig.json сгенерированный react-scripts включает все файлы в src , включая setupProxy.js . В результате он запускает VS Code, чтобы показать ошибку Cannot compile namespaces... в setupProxy.js , пометить код красной волнистой линией и включить его в панель "Проблемы". В моей настройке он также выделяет файл и все его родительские папки красным цветом.

Решение: подавите сообщение об ошибке VS Code, исключив файл setupProxy.js tsconfig.json.

{
  // ...
  "exclude": ["src/setupProxy.js"]
}

react-scripts заставляет isolatedModules: true , но, похоже, он не перезаписывает exclude .

Альтернатива: добавьте именованный экспорт в setupProxy.js:

export const _ = '';

При экспорте верхнего уровня он теперь действителен с --isolatedModules.

Очень часто разработчики получают это сообщение, потому что есть файл, который не следует включать в копилирование (gulp.js и т. Д.)

ВНИМАНИЕ - Если вы используете приложение create-response-app и видите эту проблему, как и я ... Мне удалось обойти это, внеся изменения в мой файл tsconfig.json ....

Изменение следующих

    "isolatedModules": true,

к

    "isolatedModules": false,

@UncleFifi И затем ошибка переходит от проверки типа к преобразованию машинописного текста babel, см. Первое предостережение .

@jtbennett вы можете просто ничего не экспортировать с помощью export {}; - вырожденной формы export { name, localName as exportName };

@UncleFifi И затем ошибка переходит от проверки типа к преобразованию машинописного текста babel, см. Первое предостережение .

Только если вы действительно используете пространства имен. Эта проблема в основном связана с этой ошибкой, когда возникает жалоба на пространства имен, когда вы даже не используете пространства имен, а просто имеете законный файл с импортом / экспортом.

Только если вы действительно используете пространства имен. Эта проблема в основном связана с этой ошибкой, когда возникает жалоба на пространства имен, когда вы даже не используете пространства имен, а просто имеете законный файл с импортом / экспортом.

Правильно, извините - я давно не читал эту ветку! Тем не менее, причина, по которой они устанавливают --isolatedModules в CRA, заключается в том, что он близко имитирует ограничения машинописного текста babel (поскольку babel также является однофайловой транспиляцией), поэтому вы должны хотя бы знать, что удаляете эту защиту рельс.

Итак, текущее решение ошибки Cannot compile namespaces when --isolatedModules flag is provided - добавить export {}; в начало файла?

Да, это поможет обойти проблему. (Предполагая, что вы на самом деле не используете TypeScript namespace . В противном случае у вас другая и, вероятно, законная проблема.)

Просто столкнулся с этим сообщением из-за того, что файл «пустой» файл (т.е. весь файл был закомментирован). Я счастлив, что TS поймал это, но сообщение об ошибке было чрезвычайно непрозрачным (и цвета были разбиты на ванильной установке CentOS 7, но это, вероятно, из-за сервера разработки webpack, не связанного напрямую с TS)

screen shot 2019-02-06 at 14 20 14

_Edit: невозможно воспроизвести. Я определенно смотрел на файл, состоящий только из трех экспортов верхнего уровня, и у меня была эта ошибка, но, как оказалось, я сделал что-то не так где-то еще.

Эта ошибка произошла со мной с файлом, который имеет экспорт верхнего уровня.

// Cannot compile namespaces:
export const foo = 'foo';

// Compiles fine
const foo = 'foo';
export { foo };

@ denis-sokolov Очевидный вопрос: есть ли у вас в этом файле еще что-нибудь, например, пространства имен?

Если это буквально просто export const , второе предположение будет заключаться в том, что машинописный текст используется в чем-то вроде webpack с ts-loader и видит только контент после предыдущего прохода (например, babel-loader), который расширяет export в некотором роде, но это немного натянуто.

Я больше не могу это воспроизвести. Извините, @simonbuchan , за ложную тревогу.

Понятия не имею, почему я получаю эту ошибку в этом конкретном файле.
Другие файлы работают нормально

screen shot 2019-02-18 at 12 49 07
screen shot 2019-02-18 at 12 48 34

Я нахожусь в ситуации, когда я использую CRA TypeScript и импортирую пакет, в котором нет @types . Я хочу добавить declare module 'package' чтобы предоставить свои собственные типы, но я не могу поместить этот оператор в какой-либо файл модуля. Итак, я продолжаю и создаю types.ts чтобы разместить там оператор declare module . Теперь я получаю эту ошибку.

Когда я заменяю isolatedModules на false , CRA меняет его обратно для меня. Это не решение.

Когда я добавляю export {} в файл types.ts с declare module , я получаю недопустимое имя модуля в расширении. вместо. Этой ошибки можно избежать, поместив объявление в немодульный файл, но CRA с помощью этой принудительной настройки isolatedModules заставляет каждый файл быть модулем!

Таким образом, существует круговой путь решения одной ошибки, который приводит к возникновению другой и обратно. Как это можно решить?

@Bnaya угадаете , файлы, которые работают, используют операторы импорта или экспорта? Используйте в коде только одно из require()/module.exports и import/export . В противном случае убедитесь, что все ваши файлы охвачены tsconfig include (подробные сведения об этом см. В документации.

По этой причине, среди прочего, объявления модуля
У меня было только CRA повторно добавить настройки, которые я удалил, а не изменить их обратно, но, может быть, это более настойчиво для isolatedModules?

@simonbuchan Я попробовал .d.ts но у меня это тоже не сработало, я сообщу, почему именно, не уверен, что это было. И действительно, CRA переписал эту настройку для меня.

@simonbuchan, я пробовал все вышеперечисленное

@simonbuchan Хм, ладно, .d.ts работает, я могу объявить там модуль и ввести его. Причина, по которой я изначально отказался от него, заключается в том, что для тех типизаций, которые я хочу объявить в этом модуле, мне нужно ссылаться на другие типы, но введение import в файл .d.ts приводит к тому, что он перестает работать. Я не знаю, как решить эту проблему, но это мой недостаток знаний TypeScript, который больше не имеет ничего общего с этой ошибкой.

Вот минимальный пример воспроизведения с использованием typescript @ next (полное репо на https://github.com/yang/sandbox-ts-namespaces-error):

src / a.js: (обратите внимание, ключевые слова импорта / экспорта не требуются)

module.exports = "hello"; // you could really put anything here, e.g. console.log('hello');

tsconfig.js:

{
  "compilerOptions": {
    "allowJs": true,
    "isolatedModules": true,
    "noEmit": true,
    "strict": true
  },
  "include": ["src"]
}

Ошибка:

$ ./node_modules/.bin/tsc
src/a.js:1:1 - error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided.

1 module.exports = "hello";
  ~~~~~~


Found 1 error.

Я тоже впервые столкнулся с этим через create-react-app --typescript , который инструктирует вас создать setupProxy.js (или setupTests.js). CRA также устанавливает для isolatedModules и allowJs значение true. Похоже, это не было проблемой до более поздней версии машинописного текста (я не видел ошибок с setupProxy.js при работе с машинописным текстом 3.1.x, только после обновления до 3.2.x или 3.3.x).

Обходной путь добавления файлов .js в ваш набор исключений работает при запуске tsc, но, что досадно, вы по-прежнему видите ошибки из этих файлов в редакторах языковой службы TS (пробовал и VS Code, и Webstorm). (Кажется, это отдельная и более общая проблема, связанная с языковым сервисом TS, не соблюдающим исключаемые, но я не смог найти существующую проблему для этого.) Чтобы замаскировать эту ошибку в редакторах, я добавил файлы .d.ts для файлов * .js.

Кроме того, требование или импорт файлов .js также делает исключение неэффективным, что приводит к возникновению ошибки (вне вашего редактора).

Только отключение allowJs (против того, что предлагает приложение create-response-app), похоже, работает для меня.

Я продолжаю получать эту ошибку для своего веб-воркера.

Я попытался исключить отдельный файл или папку, но у меня это не работает.

Нет возможности отменить этот параметр isolatedModules, CRA продолжает переписывать tsconfig.json.

Есть другие предложения?

@jamespfarrell Поместите export {}; где-нибудь в свой файл.

@Macil, спасибо за совет.

Я получаю такую ​​ошибку:

Ошибка при попытке импорта: "./workers/HeartBeat.worker.js" не содержит экспорт по умолчанию (импортирован как "HeartBeatWorker").

Если я добавлю:

export default {};

Я получил:

Uncaught TypeError: _workers_HeartBeat_worker_js__WEBPACK_IMPORTED_MODULE_2 __. Default не является конструктором

Разве нет способа обойти этот «изолированные модули», если не для одного файла, даже для всех файлов?

Те ошибки, которые вы получаете сейчас, не связаны с настройкой isolatedModules. Если вы отключили isolatedModules, вы все равно получите эти ошибки.

Ошибка при попытке импорта: "./workers/HeartBeat.worker.js" не содержит экспорт по умолчанию (импортирован как "HeartBeatWorker").

Где происходит эта ошибка? Похоже, вы пытаетесь импортировать экспорт по умолчанию для файла, у которого его нет, например import Foo from './workers/HeartBeat.worker.js'; . Если вы не хотите импортировать экспорт по умолчанию, измените строку импорта на import './workers/HeartBeat.worker.js'; .

Вы правы, это было что-то еще @Macil ! благодаря!

_Может быть, у кого-то еще будет такая же проблема: _ У меня была такая же ошибка, появляющаяся для нескольких файлов, которые я оставил в качестве заполнителей без содержимого, но я импортировал их в другие файлы, т.е. У меня был пустой файл styles.js, который был импортирован в другой файл компонента.

Просто добавь
image

У меня была эта ошибка для определения модуля, в котором я случайно добавил суффикс .ts вместо .d.ts , если кто-то еще совершает эту конкретную ошибку. После исправления необходимо перезагрузить сервер.

Та же ошибка. Я использую CRA

Столкнулся с этой проблемой на CRA. Я просто забыл экспортировать что-нибудь из файла:
Снимок экрана от 2019-04-22 22-24-04

Итак, у меня была эта ошибка, потому что у меня был файл .js в корневой папке моего проекта, в моем файле tsconfig.json я настроил это:

"compilerOptions": {
    ....
  },
  "include": ["src"],

Пришлось для этого переключить:

"compilerOptions": {
    ....
  },
  "include": ["src/*"],

Это исправило, но я не понимаю, почему, может кто-нибудь мне это объяснить? Насколько я понимаю, включение src приведет к удалению корневых файлов и родственных папок.

@thitemple Вы где-то

@ vort3xxx Я этого не делал. Я видел этот пост https://github.com/microsoft/TypeScript/issues/15230#issuecomment -479730947 от @DaviSpindola и попробовал. Это было

@ vort3xxx Я этого не делал. Я видел этот пост № 15230 (комментарий) от @DaviSpindola и попробовал. Это было

Та же проблема, такое же решение. TS 3.5.2.

@ThomasdenH

@simonbuchan Я попробовал .d.ts но у меня это тоже не сработало, я сообщу, почему именно, не уверен, что это было. И действительно, CRA переписал эту настройку для меня.

Столкновение с той же проблемой. Вы когда-нибудь придумали, как это решить? Определение файлов декларации .ts или .d.ts внутри приложения create response возвращает ошибку All files must be modules when the '--isolatedModules flag. Установка флага на false или удаление свойства isolatedModules полностью сбрасывается до true при запуске приложения create response.
Добавление export {} в конец файла объявления приводит к ошибке: Invalid module name in augmentation. Module '...' resolves to an untyped module at '...' .

Кто-нибудь, пожалуйста, помогите. Как добавить файлы пользовательской декларации в проект приложения create response?

Просто выяснил, есть ли у кого-то такая же проблема. Просто добавьте свои типы объявлений в файл react-app-env.d.ts в исходной папке при использовании приложения create response.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги