#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
};