작성
·
362
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
안녕하세요. 데코레이터는 사실 Node.js 진영에서 앵귤러나 Nest.js를 제외하고는 잘 쓰이지 않습니다.
JS가 코딩 입문언어로 그 외 언어들은 알지 못합니다.
그래서 데코레이터가 더 이해가 잘 안되는데요.
-> 원래 처음에는 난해한 개념입니다. 대한민국에서 개발자를 하신다면 언젠가는 꼭 자바(Java)를 배우실 날이 올 것 인데요. 그때 자세히 배우고 지금은 이런 것이구나 ~ 하고 개념만 잡고 그때 공부하셔도됩니다.
참고할만한 블로그나 기초 개념들을 알려주시면 감사하겠습니다.
-> 자바 데코레이터 구글에 검색하시면 됩니다. 파이썬도 데코레이터 많이 쓰긴 하는데, 자바가 공부하기에는 좋겠네요. 아래는 타입스크립트 관련 데코레이터 정리해놓은 링크 두겠습니당.
https://typescript-kr.github.io/pages/decorators.html
https://www.typescriptlang.org/docs/handbook/decorators.html
아래의 오류가 떠서 뭐가 문제인지 잘 모르겠습니다.
-> 에러 메세지는 인자가 잘못 되었을 때 나타나는 메세지입니다.