Typescript: namespace

hwisaac·2023년 2월 25일
0

typescript

목록 보기
2/3

TypeScriptnamespace는 코드를 구성하는 이름 충돌을 방지하고 구조화할 수 있는 기능을 제공합니다.

TypeScriptnamespace는 모듈을 나누는 데 사용될 수 있지만, 대체로 권장되지 않습니다. 대신 모듈 시스템을 사용하는 것이 좋습니다.

Namespace를 사용하는 것이 모듈 시스템을 사용하는 것보다 불편하고 복잡하기 때문입니다. Namespace를 사용하면 전역 네임스페이스에서 모든 것을 정의하게 되므로, 코드의 결합도가 높아지고, 이름 충돌이 발생할 가능성도 높아집니다.

반면 모듈 시스템을 사용하면 모듈 간의 의존성을 더 명시적으로 나타낼 수 있으며, 더 작고 독립적인 모듈을 만들어 코드를 재사용하기 쉬워집니다. 또한 모듈 시스템을 사용하면 webpack과 같은 번들러를 사용하여 코드를 번들링하고, 최적화하여 더 빠르고 효율적인 웹앱을 만들 수 있습니다.

따라서 TypeScript에서는 namespace보다는 모듈 시스템을 사용하는 것이 좋습니다.

장점과 단점

장점

  1. 이름 충돌 방지: namespace는 이름 충돌을 방지하는 데 도움이 됩니다. namespace를 사용하면 다른 파일에서도 접근 가능한 명확한 API를 정의할 수 있습니다.

  2. 코드 구조화: namespace를 사용하면 코드를 논리적인 그룹으로 구조화할 수 있습니다. 이를 통해 코드의 가독성과 유지 보수성이 향상됩니다.

  3. 파일의 분리: namespace를 사용하면 코드를 여러 파일로 분리할 수 있습니다. 이를 통해 파일 크기를 줄이고 코드를 재사용할 수 있습니다.

  4. 글로벌 네임스페이스를 피할 수 있음: namespace를 사용하면 글로벌 네임스페이스를 피할 수 있습니다. 이를 통해 전역 범위의 변수나 함수의 오염을 방지할 수 있습니다.

단점 및 한계

  1. 이름 충돌 가능성: namespace를 사용하면 이름 충돌이 일어날 가능성이 있습니다. 이를 방지하기 위해서는 namespace의 이름이 충돌하지 않도록 주의해야 합니다.

  2. 불필요한 중첩: namespace를 과도하게 사용하면 코드가 복잡해지고 가독성이 저하될 수 있습니다.

  3. 모듈 시스템 대체 불가능: namespace는 모듈 시스템과는 다른 기능이므로, 모듈 시스템을 완전히 대체하지는 못합니다. 모듈 시스템이 namespace보다 더 강력하며, 코드의 재사용성 및 유지 보수성을 높이는 데 도움이 됩니다.

  4. 네임스페이스의 명확성: namespace의 이름이 충돌하지 않도록 주의해야 합니다. 또한 namespace의 구조가 복잡해질수록 코드의 가독성이 저하될 수 있습니다. 따라서 namespace를 사용할 때는 적절한 구조를 유지하는 것이 중요합니다.

예시

namespace는 다음과 같은 방식으로 정의됩니다.

namespace MyNamespace {
  export interface MyInterface {
    // ...
  }
  export function myFunction() {
    // ...
  }
}

위의 코드에서 MyNamespacenamespace의 이름입니다. 이 namespace에는 MyInterface라는 인터페이스와 myFunction이라는 함수가 포함되어 있습니다. export 키워드를 사용하여 이 namespace에서 정의한 인터페이스 및 함수를 다른 파일에서도 사용할 수 있도록 공개할 수 있습니다.

다른 파일에서 namespace의 멤버에 접근하려면, . 연산자를 사용하여 namespace와 멤버의 이름을 결합합니다.

import { MyNamespace } from './myNamespaceFile';

const myVar: MyNamespace.MyInterface = { /* ... */ };
MyNamespace.myFunction();

위의 예제에서는 import 키워드를 사용하여 다른 파일에서 MyNamespace를 가져오고, . 연산자를 사용하여 MyNamespace에서 MyInterfacemyFunction에 접근합니다.

namespace는 코드를 구조화하고 이름 충돌을 방지하는 데 유용합니다. 하지만 모듈 시스템을 사용하는 것이 namespace보다 추천됩니다. 모듈 시스템은 namespace보다 더 강력하며, 코드의 재사용성 및 유지 보수성을 높이는 데 도움이 됩니다.

namespace 로 코드를 개선하는 예시

먼저, 아래와 같은 두 개의 파일이 있다고 가정해봅시다.

// utils.ts

function add(x: number, y: number) {
  return x + y;
}

function subtract(x: number, y: number) {
  return x - y;
}
// app.ts
console.log(add(1, 2));
console.log(subtract(4, 3));

위의 예시에서는 utils.ts 파일에 addsubtract 함수가 정의되어 있고, app.ts 파일에서 이러한 함수를 사용하고 있습니다.

그러나 이 코드는 문제가 있습니다.

utils.ts 파일에서 정의된 모든 함수는 글로벌 네임스페이스에서 동작하므로, 이름 충돌이 발생할 가능성이 있습니다.

이러한 문제를 방지하려면 utils.ts 파일의 함수를 namespace로 래핑할 수 있습니다.

namespace MathUtils {
  export function add(x: number, y: number) {
    return x + y;
  }
  export function subtract(x: number, y: number) {
    return x - y;
  }
}

위의 코드에서 MathUtils namespace는 add 및 subtract 함수를 래핑합니다. export 키워드를 사용하여 이 namespace에서 정의한 함수를 다른 파일에서도 사용할 수 있도록 공개할 수 있습니다. 이제 app.ts 파일에서 MathUtils namespace를 사용하여 함수를 호출할 수 있습니다.

import { MathUtils } from './utils';

console.log(MathUtils.add(1, 2));
console.log(MathUtils.subtract(4, 3));

위의 예시에서는 import 키워드를 사용하여 utils.ts 파일에서 MathUtils namespace를 가져오고, . 연산자를 사용하여 MathUtils에서 addsubtract 함수에 접근합니다.

이를 통해 이름 충돌을 방지하고, 코드의 구조를 더 명확하게 구성할 수 있습니다.

namespace가 적절하지 않은 경우

1. namespace 중복 문제

여러 파일에서 같은 namespace를 사용하면 이름 충돌이 발생할 수 있습니다. 이를 방지하기 위해서는 namespace의 이름이 충돌하지 않도록 주의해야 하며, 필요한 경우 namespace를 분리하는 것이 좋습니다.

// File 1
namespace MyNamespace {
  export function foo() {
    // ...
  }
}

// File 2
namespace MyNamespace {
  export function bar() {
    // ...
  }
}

위의 예시에서는 두 개의 파일에서 같은 이름의 namespace를 사용하고 있습니다. 이러한 경우, 이름 충돌이 발생할 가능성이 있으며, 예상치 못한 결과를 초래할 수 있습니다.

해결 방법: 이름 충돌을 방지하기 위해 namespace의 이름을 변경하거나, namespace를 분리하여 각각의 파일에서 별도로 정의합니다.

// File 1
namespace MyNamespace1 {
  export function foo() {
    // ...
  }
}

// File 2
namespace MyNamespace2 {
  export function bar() {
    // ...
  }
}

2. 네임스페이스 구조의 복잡성

namespace MyNamespace {
  export namespace SubNamespace {
    export function foo() {
      // ...
    }
  }
}

위의 예시에서는 namespace MyNamespace 내부에 또 다른 namespace SubNamespace가 정의되어 있습니다.

이러한 경우, namespace의 구조가 복잡해져 가독성이 떨어지고 유지 보수성이 감소할 가능성이 있습니다.

해결 방법: namespace의 구조를 최대한 간단하게 유지하고, 필요한 경우 다른 파일로 분리합니다.

// File 1
namespace MyNamespace {
  export function foo() {
    // ...
  }
}

// File 2
namespace MyNamespace {
  export function bar() {
    // ...
  }
}

3. 모듈 시스템 대체 불가능

namespace MyNamespace {
  export function foo() {
    // ...
  }
}

// 사용 예시
import { MyNamespace } from './myNamespace';

MyNamespace.foo();

위의 예시에서는 namespace를 사용하여 모듈처럼 코드를 구조화하고 있습니다.

그러나 namespace는 모듈 시스템과는 다른 기능이므로, 모듈 시스템을 완전히 대체하지는 못합니다.

해결 방법: 모듈 시스템을 사용하여 코드를 구조화하고, namespace를 사용하여 이름 충돌을 방지하거나 코드의 구조를 더 명확하게 구성합니다.

// File 1
export function foo() {
  // ...
}

// 사용 예시
import { foo } from './myModule';

foo();

위의 예시에서는 모듈 시스템을 사용하여 코드를 구조화하고, export 키워드를 사용하여 함수를 다른 파일에서도 사용할 수 있도록 공개합니다.

이를 통해 모듈 시스템의 강력한 기능을 활용할 수 있으며, 코드의 재사용성과 유지 보수성을 높일 수 있습니다.

이제 import 키워드를 사용하여 모듈을 가져오고, . 연산자를 사용하여 함수를 호출할 수 있습니다.

// File 1
export namespace MyNamespace {
  export function foo() {
    // ...
  }
}

// 사용 예시
import { MyNamespace } from './myModule';

MyNamespace.foo();

위의 예시에서는 namespace를 모듈 내부에서 사용하고, export 키워드를 사용하여 namespace에서 정의한 함수를 다른 파일에서도 사용할 수 있도록 공개합니다.

이를 통해 이름 충돌을 방지하고, 모듈 시스템의 강력한 기능과 namespace의 구조화 기능을 함께 사용할 수 있습니다.

0개의 댓글