'Невозможно повторно объявить переменную с блочной областью видимости' в несвязанных файлах

Существует простой пакет TS, который используется как модули CommonJS и не имеет экспорта. Файлы TS компилируются в файлы JS с тем же именем и используются как require('package/option-foo').

tsconfig.json:

{
  "compilerOptions": {
    "target": "es5"
  }
}

option-foo.ts:

declare const GlobalVar: any;

function baz() {}

if (GlobalVar.foo) GlobalVar.baz = baz;

option-bar.ts:

declare const GlobalVar: any;

function baz() {}

if (GlobalVar.bar) GlobalVar.baz = baz;

Здесь важно то, что option-foo и option-bar никогда не используются вместе. В проекте есть и другие дополнительные файлы TS, но они ни на что не влияют, их нужно просто перенести в JS за один tsc прогон.

Когда tsc запускается, он бросает

Невозможно повторно объявить блочную переменную GlobalVar.

Реализация дублирующей функции.

Невозможно повторно объявить блочную переменную GlobalVar.

Реализация дублирующей функции.

для GlobalVar и baz в обоих файлах.

Как с этим справиться, не усложняя процесс сборки или вывод этих двух файлов TS?


person Estus Flask    schedule 01.12.2016    source источник
comment
В этом конкретном случае у вас может быть что-то вроде custom-typings.d.ts файла и просто объявить его там, если они оба any. Вы также можете попробовать изменить желаемую компиляцию --module (попробуйте AMD / System, поскольку я считаю, что они охватывают файлы индивидуально).   -  person Seiyria    schedule 30.01.2017


Ответы (2)


TL; DR Просто напишите export {} во внешней области ваших файлов.


В какой-то момент необходимо семантическое определение того, следует ли рассматривать файл как модуль (и иметь свою собственную область видимости) или как скрипт (и совместно использовать глобальную область видимости). с другими скриптами).

В браузере это просто - у вас должна быть возможность использовать тег <script type="module"> и вы сможете использовать модули.

Но как насчет любого другого места, где используется JavaScript? К сожалению, на данный момент нет стандартного способа провести такое различие.

TypeScript решил решить эту проблему, просто заявив, что модуль - это любой файл, содержащий импорт или экспорт.

Поэтому, если в вашем файле нет каких-либо операторов верхнего уровня import или export, вы иногда будете сталкиваться с проблемами, когда глобальные объявления мешают друг другу.

Чтобы обойти это, вы можете просто иметь оператор export, который ничего не экспортирует. Другими словами, просто напишите

export {};

где-нибудь на верхнем уровне вашего файла.

person Daniel Rosenwasser    schedule 01.02.2017
comment
Поразмыслив, я закончил с этим решением, оно просто работает. Спасибо. - person Estus Flask; 05.02.2017
comment
Это лучшее объяснение этой проблемы. Эта проблема меня долго смущала. Сегодня я наконец нашел причину. - person slideshowp2; 23.06.2017
comment
так что это компилятор TS жалуется, а не проблема во время выполнения, раздражает. Есть ли способ игнорировать подобные ошибки TS? - person Alexander Mills; 22.10.2017
comment
Вы не должны пытаться игнорировать ошибки в этом случае, особенно если ошибки исходят из .ts файлов, потому что эти будут действительно конфликтуют. - person Daniel Rosenwasser; 23.10.2017
comment
Сэкономил мое время, это именно то решение, которое я искал. Было неприятно видеть множество предупреждений только из-за этого. - person Ashish Singh; 10.12.2017
comment
@DanielRosenwasser Разве это не настройка компилятора? Я подумал, что может быть moduleResolution или isolatedModules, но не повезло. Я работаю над тем, чтобы заставить truffle suite работать с TS, и это своего рода боль. - person Krzysztof Kaczor; 31.08.2018
comment
Он работает до тех пор, пока вы не получите SyntaxError: Unexpected token export. Я бы хотел, чтобы они просто согласились с тем, что это ошибка машинописного текста для NodeJS, и разработали исправление для нее. - person m12lrpv; 16.06.2020
comment
Я ценю этот прием, но добавляю, что это запах. Почему TS считает импорт повторным декларированием? Модули имеют объем. TS действительно должен исправить эту ошибку .. - person GN.; 23.09.2020
comment
У меня есть устаревший код, в котором есть эта проблема. К сожалению, добавить экспорт {} нельзя. - person Viktor M; 01.04.2021

GlobalVar, а функции доступны в глобальном пространстве имен, а TypeScript предупреждает вас, что переменная и имя метода повторно объявлены. Поскольку две функции объявлены в глобальном пространстве имен, вам нужно объявить их только один раз.

Если вы хотите это сделать, используйте пространства имен.

namespace foo {    
    declare const GlobalVar: any;
    function baz() {}
}

namespace bar {
    declare const GlobalVar: any;
    function baz() {}
}

Вы можете вызывать функции так же, как вы вызываете их в C #, используя имя пространства имен: bar.baz или foo.baz.

person freedeveloper    schedule 31.01.2017