티스토리 뷰

CS/Language

[TypeScript] Namespace

OpusK 2022. 4. 11. 07:50
반응형

Namespace

네임스페이스는 말 그대로 Name(이름)을 기반으로 나눈 Space(공간)을 의미하며,

'나누었기 때문에' 서로 구분하는데 도움이 된다. (프로그래머(휴먼)한테 좋다)

네임스페이스라는 개념이 어색하다면, 구글링을 통해 친절한 좋은 자료들을 쉽게 얻을 수 있다.

 

Namespace - Wikipedia

From Wikipedia, the free encyclopedia Jump to navigation Jump to search Container for a set of identifiers In computing, a namespace is a set of signs (names) that are used to identify and refer to objects of various kinds. A namespace ensures that all of

en.wikipedia.org

 

아무튼, TS에도 네임스페이스가 있는데, 외부 접근 허용을 위해 export를 사용하는 것을 제외하고는 C++의 사용법과 동일하다. 다만, TS는 JS로의 트랜스파일 후에 브라우저에서 동작할 수 있으므로, JS로 어떻게 변환되는지 궁금했다.

 

 

깡통 객체에 프로퍼티 추가하기 (w/ IIFE) 

바로 코드로 확인해보자. 플레이그라운드로 이것저것 수정해서 보고 싶다면 아래 링크를 활용하자.

 

TS Playground - An online editor for exploring TypeScript and JavaScript

The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.

www.typescriptlang.org

타입스크립트 코드 ( .ts )

네임스페이스 안에 선언/정의된 Class와 객체에 export가 붙어 있는 것을 볼 수 있는데, 이 키워드가 있어야지만, 외부에서 이것들을 접근할 수 있다.

namespace DatabaseEntity {
  export class User {
    constructor(public name: string) {}
  }

  export const newUser = new User("Jon");
}

namespace DatabaseEntity {
  export class UserRole {
    constructor(public user: User, public role: string) {}
  }

  export const newUserRole = (name: string, role: string) => {
    return new UserRole(new User(name), role);
  };
}

const newUser = DatabaseEntity.newUserRole("Kei", "admin");
console.log(newUser);

변환된 선언 코드 ( .d.ts )

declare namespace DatabaseEntity {
    class User {
        name: string;
        constructor(name: string);
    }
    const newUser: User;
}
declare namespace DatabaseEntity {
    class UserRole {
        user: User;
        role: string;
        constructor(user: User, role: string);
    }
    const newUserRole: (name: string, role: string) => UserRole;
}
declare const newUser: DatabaseEntity.UserRole;

변환된 JS 코드 ( .js )

"use strict";
var DatabaseEntity;
(function (DatabaseEntity) {
    class User {
        constructor(name) {
            this.name = name;
        }
    }
    DatabaseEntity.User = User;
    DatabaseEntity.newUser = new User("Jon");
})(DatabaseEntity || (DatabaseEntity = {}));
(function (DatabaseEntity) {
    class UserRole {
        constructor(user, role) {
            this.user = user;
            this.role = role;
        }
    }
    DatabaseEntity.UserRole = UserRole;
    DatabaseEntity.newUserRole = (name, role) => {
        return new UserRole(new DatabaseEntity.User(name), role);
    };
})(DatabaseEntity || (DatabaseEntity = {}));
const newUser = DatabaseEntity.newUserRole("Kei", "admin");
console.log(newUser);

여기서 재밌는 포인트를 볼 수 있다.

TS에서 네임스페이스 안에서 export 키워드를 붙여준 것만 외부에서 접근이 가능하다고 했는데, 실제로 export 키워드를 지워보면 차이를 알 수 있다.

만약 export 키워드를 지우면, 아래 코드에서 아래와 같이 글로벌하게 선언된 객체의 프로퍼티로 등록하는 코드가 없어진다.

DatabaseEntity.User = User;

C에서 구조체를 사용하여 네임스페이스 흉내를 내는 방식과 매우 유사하다.

JS에서는 네임스페이스와 동일한 이름으로 선언된 객체에 프로퍼티를 추가하기 위해, IIFE (즉시 실행 함수 표현)을 사용하여 캡슐화를 지원한다.

추가로, IIFE에서 받는 파라미터를 네임스페이스 객체 그대로 받거나 빈 객체를 받아 처리할 수 있게 하나의 파라미터를 받는 형태로 변환된 것을 볼 수 있다.

실행 결과

 

참고자료

 

How To Use Namespaces in TypeScript | DigitalOcean

 

www.digitalocean.com

 

반응형
댓글