TypeScript — объявите действительно глобальную переменную для прямого доступа, без окна, глобального или глобального

#javascript #typescript #global-variables

Вопрос:

Я хочу передать некоторые переменные среды интерфейсному приложению. Они передаются через replace как часть процесса сборки, поэтому, например: if (ENV_IS_PRODUCTION) { ... } будет оцениваться как: if (false) { ... } в скомпилированном пакете (чтобы его можно было полностью удалить с помощью минификатора).

Теперь мне нужен какой-то способ сообщить TypeScript, что ENV_IS_PRODUCTION это логическое значение. Я хочу использовать его напрямую, window.ENV_IS_PRODUCTION оценил бы window.false , чтобы это было не вариант.

Самое большее, что я сделал, — это объявил об этом на местном уровне:

 declare const ENV_IS_PRODUCTION: boolean;
 

Но я понятия не имею, как объявить об этом в глобальном масштабе. Я попытался поместить вышеупомянутое локальное определение в globals.d.ts, но это не работает. И опять же, я не могу использовать window, global или globalThis. Он должен быть доступен непосредственно как переменная, без необходимости ее импорта и без использования window/global.

Комментарии:

1. Как насчет создания какого ENV -нибудь интерфейса? И использовать его как ENV.IS_PRODUCTION ?

2. Наверное, я делаю что-то не так. Я только что передал это в globals.d.ts: declare global { interface ENV { IS_PRODUCTION: boolean } } и когда я пытаюсь его использовать, я получаю ENV, который относится только к типу, но используется как значение. То же самое с: declare interface ENV { IS_PRODUCTION: boolean } И если бы я попытался объявить его как var, он бы вообще его не выбрал.

3. В другом ответе я нашел ссылку на проект, в котором это работает должным образом: stackblitz.com/edit/… но я не могу заставить его работать с моим проектом, помещая: declare const ENV_IS_PRODUCTION: boolean; в globals.d.ts не будет работать для меня.

4. Оказывается, это проблема с vscode. Если я определяю его в globals.d.ts или добавляю в файл в каталоге typeRoots, он компилируется. Просто vscode, похоже, не знает об этом.

5. Попробуйте снова открыть редактор. Иногда VS-код не улавливает изменения в файлах d.ts и требует перезапуска

Ответ №1:

На самом деле, оказывается, локальное определение, введенное в globals.d.ts, должно работать. У меня просто были некоторые проблемы с тем, что VS — код не взял его (работал после перезапуска, но я, вероятно, не заметил, так как Eslint выдал ошибку отдельно-которую я до сих пор не решил, но она довольно незначительна).

Поэтому решение в данном случае состоит в том, чтобы просто поместить это в globals.d.ts:

 declare const ENV_IS_PRODUCTION: boolean;
 

Обновить:

Ошибка Eslint, вызвавшая путаницу, заключалась в том, что Eslnt, похоже, не распознает типы, определенные подобным образом. Решение состоит в том, чтобы отключить правило no-undef для всех файлов машинописи — в любом случае оно избыточно, так как tsc в любом случае не допустит неопределенную переменную. https://github.com/typescript-eslint/typescript-eslint/issues/342

Обновление 2:

Я добавлю, что еще одна причина, по которой это не сработало для меня изначально, заключается в том, что, похоже, что — то не так с globals.d.ts, когда у меня было это определение и объявление об объекте окна в одном globals.d.ts-это тоже не сработало. Я остановился на использовании compilerOptions.typeRoots и поместил туда файлы типов вместо использования globals.d.ts, и это работает нормально.

Так что лучшее решение-это:

tsconfig.json

 {
  ...
  "compilerOptions": {
    ...
    "typeRoots": [
      "./node_modules/@types",
      "./src/types"
    ]
   }
}
 

src/типы/env.d.ts

 declare const ENV: {
  IS_PRODUCTION: boolean
};