프로그래밍프론트엔드 개발자

TypeScript에서 Namespace란 무엇이며, 왜 사용되며, 모듈(module)과는 어떻게 다른가요?

Hintsage AI 어시스턴트로 면접 통과

답변.

Namespace(이름 공간)란 코드 조직화 메커니즘으로, pre-ES6 시절부터 논리적으로 관련된 엔티티를 결합하기 위해 사용되었습니다. 이는 클래스, 함수, 인터페이스 및 타입을 단일 이름 공간 내에 그룹화하여 이름 충돌을 피하고 코드를 더 읽기 쉽게 만들어 대규모 프로젝트를 구조화하는 데 도움을 줍니다.

문제의 역사: JavaScript ES6 표준이 등장하기 전, 개발자들은 IIFE, 객체 및 이름 공간을 사용해 모듈성을 모방했습니다. TypeScript는 코드를 그룹화하기 위해 namespace(이전에는 internal module) 키워드를 도입했습니다.

문제: 현대 모듈(ES6 Module)이 표준이 되었고, 두 접근 방식(이름 공간 및 모듈)이 동시에 존재하여 아키텍처 설계에 혼란을 야기합니다. 언제 이름 공간(namespace)을 사용하고 언제 모듈(module)을 사용하는 것이 더 좋을까요?

해결책: 이름 공간은 여전히 순수 TypeScript 프로젝트에서 보조 함수 및 타입을 그룹화하는 데 유용합니다(예: outFile 출력으로 단일 JS 파일 생성 시). 특히 npm 및 현대 빌드 도구와 함께 작업할 때는 모듈을 사용하는 것이 더 적절합니다. 이름 공간은 내부 라이브러리, 타입 선언 및 하나의 파일 내에서 구조화가 필요하거나 오래된 코드에서 자주 사용됩니다.

코드 예제:

namespace MyMath { export function add(a: number, b: number) { return a + b; } } console.log(MyMath.add(2, 3)); // 5

주요 특징:

  • 논리적으로 관련된 코드를 결합할 수 있음
  • 클래스, 타입, 함수, 상수 등을 포함할 수 있음
  • outFile 옵션과 함께 사용되며, 현대 프로젝트에서 모듈과 함께 사용하는 경우는 드뭅니다.

속임수 질문.

다른 파일의 namespace를 결합하면 하나의 namespace가 될까요, 아니면 여러 개가 될까요?

TypeScript는 _declaration merging_을 수행하며, 이름이 일치할 경우 이름 공간의 서로 다른 부분이 올바르게 연결되고 동일한 범위에 있는 경우 하나로 합쳐집니다.

// mathA.ts namespace MathUtil { export function sum(a: number, b: number) { return a + b; } } // mathB.ts namespace MathUtil { export function mul(a: number, b: number) { return a * b; } } // 컴파일 후 MathUtil은 두 메서드를 포함합니다.

namespace를 모듈처럼 import/require할 수 있을까요?

아니요, namespace는 기본 내보내기/이름 내보내기가 없으며, ES6 표준 구문으로 가져올 수 없습니다. Namespace는 순수 TypeScript 개념으로, JavaScript 모듈로 변환되지 않습니다.

다른 파일에서 import를 통해 namespace의 값을 가져올 수 있나요?

아니요, 다른 파일에서 namespace에 접근하려면 reference(/// <reference path="..." />)를 사용해야 하며, outFile로 컴파일해야 합니다. import를 통한 가져오는 것은 불가능합니다.

일반적인 오류 및 안티 패턴

  • 하나의 프로젝트에서 namespace와 모듈을 혼합하기
  • 모듈처럼 namespace를 가져오려고 시도하기
  • 코드의 작은 부분마다 namespace를 사용하는 것(단편화)

삶의 예

부정적인 사례

오래된 프로젝트에서 로직을 수십 개의 namespace로 나누었고, 동일한 이름이 여러 파일에 나타나면서 예상치 못한 결합이나 충돌이 발생했습니다. 모듈 아키텍처로 전환하면서 코드 이식이 매우 힘들어졌습니다.

장점:

  • 함수의 빠른 그룹화
  • 작은 스크립트에 간단함

단점:

  • 실제 모듈과 혼란을 야기함
  • 확장하기 어렵습니다.
  • 파일 간의 의존성 관리가 복잡함

긍정적인 사례

큰 라이브러리에서 namespace 선언을 통해 index.d.ts 파일에 API를 선언하여 모든 타입과 인터페이스를 구현 코드 없이 통일시켰습니다. 이를 통해 라이브러리의 소비자를 신속하게 유형화하고 팀 간의 계약을 쉽게 업데이트할 수 있었습니다.

장점:

  • API의 명확한 그룹화
  • 계약 업데이트의 용이함

단점:

  • 모듈에서 새로운 프로젝트에 통합하기 더 어려움
  • npm 자동 설명서 지원이 안 됨