Как обратиться к глобальной переменной внутри модуля в TypeScript?
Проблема: TypeScript не знает о глобальных переменных
Когда вы работаете с модулями (файлы с import/export), TypeScript изолирует код. Глобальные переменные, объявленные вне модуля, не видны автоматически — нужно явно сообщить TypeScript об их существовании.
Ошибка Property 'myApp' does not exist on type 'Window' возникает, потому что стандартный тип Window не содержит свойства myApp. Решение — расширить интерфейс Window через объявление (declaration).
Решение №1: Расширение интерфейса Window
Создайте файл global.d.ts (или добавьте в существующий файл деклараций) и расширьте интерфейс:
// global.d.ts
interface Window {
myApp: {
apiBaseUrl: string;
debugMode: boolean;
// Добавьте другие поля по мере необходимости
};
}
Теперь в любом модуле вы можете писать:
// main.ts
const config = window.myApp; // ✅ Ошибки нет
console.log(config.apiBaseUrl); // 'https://api.example.com'
Решение №2: Использование declare global
Если вы хотите объявить прямо в модуле, используйте конструкцию declare global:
// main.ts
import { fetchData } from './api';
declare global {
interface Window {
myApp: {
apiBaseUrl: string;
debugMode: boolean;
};
}
}
const config = window.myApp;
console.log(config.apiBaseUrl);
Этот способ удобен, когда глобальная переменная используется только в одном файле. Для многократного использования лучше вынести в .d.ts.
Важные моменты:
- Глобальные переменные должны существовать во время выполнения — они объявлены в
config.js, который загружается до модуля. - Не злоупотребляйте глобальными переменными — в модульной системе лучше передавать конфигурацию через импорт или DI (внедрение зависимостей).
- Для сложных объектов опишите полный интерфейс, чтобы TypeScript проверял типы полей.
Пример полной настройки:
// types/global.d.ts
interface AppConfig {
apiBaseUrl: string;
debugMode: boolean;
version: string;
}
interface Window {
myApp: AppConfig;
}
// main.ts
const config: AppConfig = window.myApp;
// Теперь TypeScript знает все поля config
Альтернативный подход: избегать глобальных переменных
Лучшая практика — передавать конфигурацию через модули:
// config.ts
export const appConfig = {
apiBaseUrl: 'https://api.example.com',
debugMode: true
};
// main.ts
import { appConfig } from './config';
console.log(appConfig.apiBaseUrl); // ✅ Чисто, типобезопасно
Этот подход избавляет от необходимости расширять Window и делает код более предсказуемым.
Дополнительный подход: Использование declare var
Если вы не хотите расширять интерфейс Window, можно объявить глобальную переменную напрямую с помощью declare var или declare const:
// main.ts
declare const myApp: {
apiBaseUrl: string;
debugMode: boolean;
};
// Использование:
console.log(myApp.apiBaseUrl); // ✅ Работает
Этот метод создаёт глобальную переменную myApp в области видимости модуля, но не привязывает её к window. Если ваша переменная действительно находится на window, такой подход может привести к путанице — TypeScript будет считать, что переменная существует сама по себе, хотя на самом деле она доступна через window.myApp.
Когда использовать: Если глобальная переменная объявлена не на window, а через var в глобальной области видимости (например, в скрипте без модулей). Но в современных проектах это редкость — обычно всё привязано к window.
Совет: Используйте модули
Лучший способ избежать таких проблем — перестать полагаться на глобальные переменные. Вынесите конфигурацию в отдельный модуль и импортируйте её. Это сделает код чище, тестируемее и понятнее для TypeScript.
// config.ts
export const API_CONFIG = {
baseUrl: 'https://api.example.com',
debug: true
};
// main.ts
import { API_CONFIG } from './config';
// Теперь никаких глобальных переменных!
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги