인프런 커뮤니티 질문&답변

e951219님의 프로필 이미지
e951219

작성한 질문수

타입스크립트의 모든 것

색션 2, 데코레이터 개념이 아예 이해가 안됩니다.

작성

·

367

0

 

 

안녕하세요. 타입스크립트 강좌 수강생 어민규입니다.

데코레이터를 이해하기 위해 필요한 기초지식들을 공부하기 위해 질문을 드립니다.


JS가 코딩 입문언어로 그 외 언어들은 알지 못합니다.
그래서 데코레이터가 더 이해가 잘 안되는데요.

 

참고할만한 블로그나 기초 개념들을 알려주시면 감사하겠습니다.

또한 데코레이터 -2 강의를 기반으로 한 프로그램에서
아래의 오류가 떠서 뭐가 문제인지 잘 모르겠습니다.


// 데코레이터 - 2

// 팩토리
// : 데코레이터 함수를 리턴하면서 감싸고 있는 녀석

// f(g(x)) ----> f () { return g () }, g: 데코레이터 함수
// g ----> f(g(x)), f: 데코레이터 팩토리 (목적: 인자전달, param 전달)


// 1. 데코레이터는 함수다
function Controller(constructor: any): any {
  console.log("Controller : ", constructor)

  return (target: any) => {
    console.log(target)
  }
}

function Get(params: any): any {
  // console.log("[GET] ", params)
}

function Post(params: any): any {
  // console.log("[GET] deco start")
}

function Column(params: any): any {
  // console.log("Column!!", params)
}

function UseGuard(): any {
  // console.log('UseGuard deco start')
}


// 2. 데코레이터는 무조건 class만 같이 쓴다. (내부 외부, 맴버 변수, 메소드, 파라미터...)

// 데코레이터는 이렇게 쓴다.
@Controller('/api/v1')
class ExampleController {
  @Column('email')
  private _email: string;

  constructor(email: string) {
    this._email = email; // _email 변수를 생성자에서 초기화합니다.
  }

  @Get('/user')
  getReq() {}

  @Post('/board')
  postReq() {}
}

 

// 데코레이터 - 2
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
    function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
    var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
    var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
    var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
    var _, done = false;
    for (var i = decorators.length - 1; i >= 0; i--) {
        var context = {};
        for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
        for (var p in contextIn.access) context.access[p] = contextIn.access[p];
        context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
        var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
        if (kind === "accessor") {
            if (result === void 0) continue;
            if (result === null || typeof result !== "object") throw new TypeError("Object expected");
            if (_ = accept(result.get)) descriptor.get = _;
            if (_ = accept(result.set)) descriptor.set = _;
            if (_ = accept(result.init)) initializers.unshift(_);
        }
        else if (_ = accept(result)) {
            if (kind === "field") initializers.unshift(_);
            else descriptor[key] = _;
        }
    }
    if (target) Object.defineProperty(target, contextIn.name, descriptor);
    done = true;
};
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
    var useValue = arguments.length > 2;
    for (var i = 0; i < initializers.length; i++) {
        value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
    }
    return useValue ? value : void 0;
};
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
    if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
    return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
};
// 팩토리
// : 데코레이터 함수를 리턴하면서 감싸고 있는 녀석
// f(g(x)) ----> f () { return g () }, g: 데코레이터 함수
// g ----> f(g(x)), f: 데코레이터 팩토리 (목적: 인자전달, param 전달)
// 1. 데코레이터는 함수다
function Controller(constructor) {
    console.log("Controller : ", constructor);
    return function (target) {
        console.log(target);
    };
}
function Get(params) {
    // console.log("[GET] ", params)
}
function Post(params) {
    // console.log("[GET] deco start")
}
function Column(params) {
    // console.log("Column!!", params)
}
function UseGuard() {
    // console.log('UseGuard deco start')
}
// 2. 데코레이터는 무조건 class만 같이 쓴다. (내부 외부, 맴버 변수, 메소드, 파라미터...)
// 데코레이터는 이렇게 쓴다.
var ExampleController = function () {
    var _classDecorators = [Controller('/api/v1')];
    var _classDescriptor;
    var _classExtraInitializers = [];
    var _classThis;
    var _instanceExtraInitializers = [];
    var __email_decorators;
    var __email_initializers = [];
    var _getReq_decorators;
    var _postReq_decorators;
    var ExampleController = _classThis = /** @class */ (function () {
        function ExampleController_1(email) {
            this._email = (__runInitializers(this, _instanceExtraInitializers), __runInitializers(this, __email_initializers, void 0));
            this._email = email; // _email 변수를 생성자에서 초기화합니다.
        }
        ExampleController_1.prototype.getReq = function () { };
        ExampleController_1.prototype.postReq = function () { };
        return ExampleController_1;
    }());
    __setFunctionName(_classThis, "ExampleController");
    (function () {
        var _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
        __email_decorators = [Column('email')];
        _getReq_decorators = [Get('/user')];
        _postReq_decorators = [Post('/board')];
        __esDecorate(_classThis, null, _getReq_decorators, { kind: "method", name: "getReq", static: false, private: false, access: { has: function (obj) { return "getReq" in obj; }, get: function (obj) { return obj.getReq; } }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _postReq_decorators, { kind: "method", name: "postReq", static: false, private: false, access: { has: function (obj) { return "postReq" in obj; }, get: function (obj) { return obj.postReq; } }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(null, null, __email_decorators, { kind: "field", name: "_email", static: false, private: false, access: { has: function (obj) { return "_email" in obj; }, get: function (obj) { return obj._email; }, set: function (obj, value) { obj._email = value; } }, metadata: _metadata }, __email_initializers, _instanceExtraInitializers);
        __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
        ExampleController = _classThis = _classDescriptor.value;
        if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        __runInitializers(_classThis, _classExtraInitializers);
    })();
    return ExampleController = _classThis;
}();

 

 

  • 오류 메시지
    eominkyu@pisimingyuui-MacBookAir typeScript % tsc deco && node deco

Controller : /api/v1

/Users/eominkyu/Desktop/typeScript/deco.js:13

var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);

^

TypeError: (0 , decorators[i]) is not a function

at __esDecorate (/Users/eominkyu/Desktop/typeScript/deco.js:13:40)

at /Users/eominkyu/Desktop/typeScript/deco.js:90:9

at /Users/eominkyu/Desktop/typeScript/deco.js:97:7

at Object.<anonymous> (/Users/eominkyu/Desktop/typeScript/deco.js:99:2)

at Module._compile (node:internal/modules/cjs/loader:1254:14)

at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)

at Module.load (node:internal/modules/cjs/loader:1117:32)

at Module._load (node:internal/modules/cjs/loader:958:12)

at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)

at node:internal/main/run_main_module:23:47

Node.js v18.16.0

답변 1

0

yongsoocho님의 프로필 이미지
yongsoocho
지식공유자

안녕하세요. 데코레이터는 사실 Node.js 진영에서 앵귤러나 Nest.js를 제외하고는 잘 쓰이지 않습니다.

JS가 코딩 입문언어로 그 외 언어들은 알지 못합니다.
그래서 데코레이터가 더 이해가 잘 안되는데요.
-> 원래 처음에는 난해한 개념입니다. 대한민국에서 개발자를 하신다면 언젠가는 꼭 자바(Java)를 배우실 날이 올 것 인데요. 그때 자세히 배우고 지금은 이런 것이구나 ~ 하고 개념만 잡고 그때 공부하셔도됩니다.

참고할만한 블로그나 기초 개념들을 알려주시면 감사하겠습니다.
-> 자바 데코레이터 구글에 검색하시면 됩니다. 파이썬도 데코레이터 많이 쓰긴 하는데, 자바가 공부하기에는 좋겠네요. 아래는 타입스크립트 관련 데코레이터 정리해놓은 링크 두겠습니당.
https://typescript-kr.github.io/pages/decorators.html
https://www.typescriptlang.org/docs/handbook/decorators.html

아래의 오류가 떠서 뭐가 문제인지 잘 모르겠습니다.
-> 에러 메세지는 인자가 잘못 되었을 때 나타나는 메세지입니다.


e951219님의 프로필 이미지
e951219

작성한 질문수

질문하기