TL;DR
순수 타입스크립트, Next.js 환경에서의 사용법:
/* eslint-disable no-var */
export {};
declare global {
var myGlobalVar: string;
interface Window {
myCustomVar: string;
}
}
ts
Vite 기반 프레임워크(Nuxt, SvelteKit, Astro)에서의 사용법:
/// <reference types="vite/client" />
const myGlobalVar: string;
interface Window {
myCustomVar: string;
}
ts
들어가면서
타입스크립트로 개발하다 보면 전역 변수의 타입을 선언해야 할 때가 있습니다.
기본 선언 방법부터 간단한 활용 예시를 살펴봅시다.
타입 선언 방법
타입스크립트에서 전역 변수의 타입은 declare
를 통해서 선언할 수 있습니다.
참고로 VSCode 같은 IDE에서 이렇게 선언된 타입을 참고하여 코드 자동 완성을 지원해줍니다.
declare var var myGlobalVar: string
myGlobalVar: string;
myG- myGlobalVar
;
//
ts
만약 타입을 여러 파일에 적용시키려면, 네 가지 디테일을 확인하면 좋을 것 같습니다.
첫째는 declare global {}
안에 타입을 선언하는 것입니다.
declare global {
var myGlobalVar: string;
}
ts
둘째는 .d.ts
확장자 파일에서 타입을 선언하는 것입니다.
해당 파일은 오로지 타입 정의만을 위한 것임을 명시하여, 관심사를 분리할 수 있어 코드를 보다 더 쉽게 관리할 수 있게 됩니다. 자세한 내용은 조금 다른 타입스크립트 .d.ts 포스트를 참고바랍니다.
declare global {
var myGlobalVar: string;
}
ts
셋째는 파일 최상단에 export {};
를 추가하는 것입니다.
이는 타입스크립트 파일에 import/export
구문이 있어야 타입스크립트 컴파일러는 해당 파일을 모듈 스크립트(type=“module”)로 인식하게 되기 때문입니다. 만약 이 구문이 없다면 컴파일러는 이 파일을 일반 스크립트(type=“text/javascript”)로 간주하게 되어, 선언된 타입을 다른 파일에서 사용할 수 없게 됩니다.
export {};
declare global {
var myGlobalVar: string;
}
ts
넷째는 tsconfig.json
에서 해당 파일이 include
되어야 동작한다는 것입니다.
타입스크립트 컴파일러가 해당 파일을 참조해야 의도대로 타입이 추론됩니다. .d.ts
파일도 .ts
로 끝나기에 보통 **/*.ts
같은 패턴으로 포함시키면 됩니다. 만약 특정 경로에 타입 정의 파일이 있다면 해당 경로를 명시적으로 추가해주는 것이 좋습니다.
{
"compilerOptions": {
"skipLibCheck": true,
//...truncated...
},
"include": ["**/*.ts"],
"exclude": ["node_modules"],
}
jsonc
ESLint의 no-var 규칙 대응
ESLint의 no-var 규칙으로 인해 Unexpected var
오류가 표기될 수 있습니다.
export {};
declare global {
var myGlobalVar: string;}
ts
var
대신 const
를 사용하면 ESLint 오류가 해소되지만, IDE에서 전역 객체에서 해당 변수를 알지 못하게 되어 타입 추론에 오류가 발생하게 됩니다.
이는 var
의 경우 전역 스코프에서 선언하면 자동으로 전역 객체의 속성으로 할당되는 반면에, let
과 const
는 블록 스코프를 가지기에 전역 스코프에서 선언해도 전역 객체의 속성으로 추가되지 않습니다.
자바스크립트 언어 특성상 어쩔 수 없이 var
를 사용해야 하기에, 해당 파일에선 no-var
규칙을 무시하는 것을 추천합니다.
/* eslint-disable no-var */
export {};
declare global {
var myGlobalVar: string;
}
ts
window
브라우저에서의 전역 객체인 window
에 타입을 확장하려면 declare global
안에서 Window
인터페이스를 명시하면 됩니다.
export {};
declare global {
interface Window {
/**
* 커스텀 변수 설명
*/
Window.myCustomVar: string
커스텀 변수 설명myCustomVar: string;
}
}
/// ---cut---
var console: Console
The `console` module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
* A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream.
* A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and
[`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module.
_**Warning**_: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for
more information.
Example using the global `console`:
```js
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
```
Example using the `Console` class:
```js
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
```console.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html)
(the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)).
```js
const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
```
See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args) for more information.log(var window: Window & typeof globalThis
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/window)window.Window.myCustomVar: string
커스텀 변수 설명myCustomVar);
ts
global, globalThis
global
는 Node.js에서의 전역 객체입니다.
globalThis
는 ESM에서의 전역 객체에 대한 참조입니다. ES2020에서 도입된 표준으로, 브라우저와 Node.js 등 모든 자바스크립트 런타임에서 동일하게 동작합니다.
declare global
로 타입을 선언하면 똑같이 적용이 됩니다.
export {};
declare global {
/**
* 커스텀 변수 설명
*/
var var myGlobalThisVar: string
커스텀 변수 설명myGlobalThisVar: string;
}
/// ---cut---
var console: Console
The `console` module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
* A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream.
* A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and
[`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module.
_**Warning**_: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for
more information.
Example using the global `console`:
```js
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
```
Example using the `Console` class:
```js
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
```console.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html)
(the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)).
```js
const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
```
See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args) for more information.log(var myGlobalThisVar: string
커스텀 변수 설명myGlobalThisVar);
var console: Console
The `console` module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
* A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream.
* A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and
[`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module.
_**Warning**_: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for
more information.
Example using the global `console`:
```js
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
```
Example using the `Console` class:
```js
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
```console.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html)
(the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)).
```js
const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
```
See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args) for more information.log(var global: typeof globalThis
global.var myGlobalThisVar: string
커스텀 변수 설명myGlobalThisVar);
var console: Console
The `console` module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
* A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream.
* A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and
[`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module.
_**Warning**_: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for
more information.
Example using the global `console`:
```js
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
```
Example using the `Console` class:
```js
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
```console.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html)
(the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)).
```js
const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
```
See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args) for more information.log(module globalThis
globalThis.var myGlobalThisVar: string
커스텀 변수 설명myGlobalThisVar);
ts
현대 프레임워크
Vite의 경우 번들러 단에서 전역 객체 타입에 대한 지원을 제공합니다. declare global {}
없이 vite-env.d.ts
에서 바로 타입을 명시하면 됩니다.
https://ko.vite.dev/guide/env-and-mode#intellisense-for-typescript
/// <reference types="vite/client" />
const myGlobalVar: string;
interface Window {
myCustomVar: string;
}
ts
반면 Next.js는 Webpack 기반이고, 프레임워크 단에서 별도 기능을 제공해주지 않기에 기존처럼 declare global {}
안에 타입을 명시해야 합니다.
https://nextjs.org/docs/app/api-reference/config/typescript#custom-type-declarations
맺으면서
전역 변수 타입 선언은 프로젝트의 유지보수성과 타입 안정성을 높이는 중요한 요소입니다. 사용법을 잘 확인하셔서 모두 Type-Safe한 코드를 작성했으면 좋겠습니다.