네임스페이스 사용법
타입스크립트는 초기 버전부터 코드 조직화를 위한 네임스페이스(Namespaces) 기능을 제공해왔습니다. 이는 자바스크립트의 전역 스코프 오염을 방지하고, 관련된 코드들을 하나의 논리적인 단위로 묶는 데 사용되었습니다. 하지만 ES 모듈 시스템이 자바스크립트 표준으로 자리 잡고 타입스크립트에서도 강력하게 지원되면서, 이제 네임스페이스의 사용은 대부분의 현대 타입스크립트 프로젝트에서 권장되지 않습니다.
그럼에도 불구하고 네임스페이스의 개념과 사용법을 이해하는 것은 중요합니다. 기존의 레거시 코드베이스를 다루거나, ES 모듈이 도입되기 전의 타입스크립트 코드를 분석할 때 마주칠 수 있기 때문입니다. 또한, 네임스페이스는 타입스크립트 내부적으로 타입 정의 파일(d.ts
)에서 전역 객체나 외부 라이브러리의 구조를 모델링하는 데 여전히 사용되기도 합니다.
네임스페이스의 선언과 구성
네임스페이스는 namespace
키워드를 사용하여 선언합니다. 네임스페이스 내부에 선언된 변수, 함수, 클래스 등은 기본적으로 해당 네임스페이스의 스코프 내에 캡슐화됩니다.
// Validators.ts
namespace Validators {
export interface StringValidator { // 네임스페이스 외부에서 사용하려면 export 필요
isValid(s: string): boolean;
}
export class ZipCodeValidator implements StringValidator {
isValid(s: string): boolean {
return s.length === 5 && /^\d+$/.test(s);
}
}
// 내부적으로만 사용되는 함수 (export 하지 않음)
function isLetter(char: string): boolean {
return /[a-zA-Z]/.test(char);
}
export class LettersOnlyValidator implements StringValidator {
isValid(s: string): boolean {
for (let i = 0; i < s.length; i++) {
if (!isLetter(s[i])) { // 네임스페이스 내부에서는 자유롭게 접근 가능
return false;
}
}
return true;
}
}
}
위 예시에서 Validators
네임스페이스는 StringValidator
인터페이스, ZipCodeValidator
클래스, LettersOnlyValidator
클래스를 포함합니다. isLetter
함수는 export
되지 않았으므로 네임스페이스 내부에서만 사용 가능합니다.
네임스페이스 멤버 사용하기
네임스페이스 내부에 export
된 멤버를 사용하려면, 네임스페이스 이름을 접두사로 붙여 접근해야 합니다.
// app.ts
// 네임스페이스 파일이 컴파일될 때 자동으로 포함되도록 설정하거나,
// HTML 파일에서 <script> 태그 순서에 맞게 추가해야 함 (일반적인 웹팩/Vite 환경에서는 잘 사용되지 않음)
let zipValidator = new Validators.ZipCodeValidator();
let lettersValidator = new Validators.LettersOnlyValidator();
let zipCode = "12345";
let text = "Hello";
console.log(`"${zipCode}" is valid zip code: ${zipValidator.isValid(zipCode)}`); // true
console.log(`"${text}" consists of letters only: ${lettersValidator.isValid(text)}`); // true
// console.log(Validators.isLetter("a")); // Error: 'isLetter' 속성이 'typeof Validators' 형식에 없습니다. (export 되지 않아서)
네임스페이스의 멤버에 접근하는 방식은 객체의 속성에 접근하는 것과 유사합니다. Validators.ZipCodeValidator
, Validators.LettersOnlyValidator
와 같이 사용합니다.
다중 파일 네임스페이스
네임스페이스는 여러 파일에 걸쳐 확장될 수 있습니다. 동일한 이름의 네임스페이스를 여러 파일에서 선언하면, 타입스크립트 컴파일러는 이들을 하나의 논리적인 네임스페이스로 병합합니다.
// Validators.ZipCode.ts
namespace Validators {
export class ZipCodeValidator {
isValid(s: string): boolean {
return s.length === 5 && /^\d+$/.test(s);
}
}
}
// Validators.LettersOnly.ts
namespace Validators {
export class LettersOnlyValidator {
isValid(s: string): boolean {
return /^[A-Za-z]+$/.test(s);
}
}
}
이렇게 두 파일을 컴파일하면, 마치 하나의 파일에 모든 내용이 정의된 것처럼 Validators
네임스페이스를 사용할 수 있습니다. tsc
명령어 사용 시 모든 관련 파일을 함께 컴파일해야 합니다. (예: tsc Validators.ZipCode.ts Validators.LettersOnly.ts app.ts --outFile output.js
)
네임스페이스 별칭
네임스페이스 이름이 길거나 여러 계층으로 중첩되어 있을 경우, import =
문법을 사용하여 별칭(alias)을 부여할 수 있습니다. 이는 코드 가독성을 높이는 데 도움이 됩니다.
namespace MyUtility.DataValidation {
export class PhoneNumberValidator {
isValid(phone: string): boolean {
return phone.length > 7;
}
}
}
// 긴 네임스페이스에 별칭 부여
import Validator = MyUtility.DataValidation;
let phoneValidator = new Validator.PhoneNumberValidator();
console.log(`"123-456-7890" is a valid phone number: ${phoneValidator.isValid("123-456-7890")}`); // true
여기서 사용된 import Validator = MyUtility.DataValidation;
구문은 ES 모듈의 import
구문과는 완전히 다른 문법이며, 오직 네임스페이스 별칭을 위해 사용됩니다.
네임스페이스 사용의 한계와 ES 모듈로의 전환
네임스페이스는 자바스크립트 파일들이 HTML script
태그를 통해 전역 스코프에 순서대로 로드되는 환경(특히 웹팩과 같은 번들러가 없던 시절)에서 유용했습니다. 그러나 다음과 같은 한계점 때문에 ES 모듈이 더 선호됩니다.
- 컴파일 순서 및 번들링 문제: 여러 파일에 걸쳐 나뉜 네임스페이스를 사용하려면, 컴파일 시 파일들의 순서를 정확히 지정하거나
--outFile
옵션을 사용하여 하나의 파일로 번들링해야 하는 복잡성이 있었습니다. ES 모듈은 이러한 의존성 관리를 언어 차원에서 제공하므로 번들러가 훨씬 효율적으로 처리할 수 있습니다. - 전역 스코프 오염 가능성:
export
되지 않은 네임스페이스 내부 멤버는 캡슐화되지만, 네임스페이스 자체는 여전히 전역 스코프에 선언됩니다. 이름 충돌 가능성이 완전히 사라지는 것은 아닙니다. ES 모듈은 파일 자체가 모듈 스코프를 형성하므로, 각 파일 내부의 최상위 레벨 선언도 기본적으로 전역 스코프를 오염시키지 않습니다. - 표준화 부재: 네임스페이스는 타입스크립트 고유의 기능이며 자바스크립트 표준에는 없습니다. 반면 ES 모듈은 자바스크립트의 공식 표준입니다. 표준을 따르는 것이 장기적인 유지보수와 생태계 호환성에 유리합니다.
권장 사항: 새로운 프로젝트를 시작하거나 기존 네임스페이스 코드를 리팩토링할 때는 항상 ES 모듈 시스템(import
/export
)을 사용하는 것이 강력히 권장됩니다. ES 모듈은 더 명확한 의존성 관리, 더 나은 트리 셰이킹(Tree Shaking) 지원(사용되지 않는 코드 제거), 그리고 자바스크립트 생태계 전반의 표준화라는 이점을 제공합니다.
네임스페이스는 타입스크립트가 처음 등장했을 때 코드 조직화를 돕는 중요한 기능이었지만, 이제는 ES 모듈 시스템이 그 역할을 대체했습니다. 비록 현대 개발에서는 거의 사용되지 않지만, 기존 코드를 이해하거나 특정 레거시 환경을 다룰 때 네임스페이스의 개념을 알고 있는 것이 여전히 유용할 수 있습니다