Typescript: ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ

์— ๋งŒ๋“  2015๋…„ 03์›” 07์ผ  ยท  139์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: microsoft/TypeScript

ES7 ์ œ์•ˆ

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์œ„ํ•œ ES7 ์ œ์•ˆ์€ https://github.com/wycats/javascript-decorators ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ES7 ์ œ์•ˆ์€ ์ด ์ œ์•ˆ์˜ ๊ธฐ๋ฐ˜์ด ๋ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ์œ ํ˜• ์‹œ์Šคํ…œ์— ๋Œ€ํ•œ ์ฐธ๊ณ  ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๋Œ€์ƒ:

ํด๋ž˜์Šค ์ƒ์„ฑ์ž

@F("color")
<strong i="12">@G</strong>
class Foo {
}

์„คํƒ• ์ œ๊ฑฐ:

var Foo = (function () {
    function Foo() {
    }
    Foo = __decorate([F("color"), G], Foo);
    return Foo;
})();

ํ–‰๋™ ์–‘์‹

class Foo {
  @F(color)
  <strong i="19">@G</strong>
  bar() { }
}

์„คํƒ• ์ œ๊ฑฐ:

var Foo = (function () {
    function Foo() {
    }
    Foo.prototype.bar = function () {
    };
    Object.defineProperty(Foo.prototype, "bar", __decorate([F(color), G], Foo.prototype, "bar", Object.getOwnPropertyDescriptor(Foo.prototype, "bar")));
    return Foo;
})();

์ •์  ๋ฉ”์„œ๋“œ

class Foo {
    @F("color")
    <strong i="26">@G</strong>
    static sMethod() {}
}

์„คํƒ• ์ œ๊ฑฐ:

var Foo = (function () {
    function Foo() {
    }
    Foo.sMethod = function () {
    };
    Object.defineProperty(Foo, "sMethod", __decorate([F("color"), G], Foo, "sMethod", Object.getOwnPropertyDescriptor(Foo, "sMethod")));
    return Foo;
})();

์†์„ฑ

class Foo {
    @F("color")
    <strong i="33">@G</strong>
    prop: number;
}

์„คํƒ• ์ œ๊ฑฐ:

var Foo = (function () {
    function Foo() {
    }
    __decorate([F("color"), G], Foo.prototype, "prop");
    return Foo;
})();

๋ฉ”์„œ๋“œ/์ ‘๊ทผ์ž ํ˜•์‹ ๋งค๊ฐœ๋ณ€์ˆ˜

class Foo {
    method(<strong i="40">@G</strong> a, @F("color") b) {}
}

์„คํƒ• ์ œ๊ฑฐ:

var Foo = (function () {
    function Foo() {
    }
    Foo.prototype.method = function (a, b) {
    };
    __decorate([G], Foo.prototype, "method", 0);
    __decorate([F("color")], Foo.prototype, "method", 1);
    return Foo;
})();

์—ฌ๊ธฐ์„œ __decorate๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜๋ฉ๋‹ˆ๋‹ค.

var __decorate = this.__decorate || function (decorators, target, key, value) {
    var kind = typeof (arguments.length == 2 ? value = target : value);
    for (var i = decorators.length - 1; i >= 0; --i) {
        var decorator = decorators[i];
        switch (kind) {
            case "function": value = decorator(value) || value; break;
            case "number": decorator(target, key, value); break;
            case "undefined": decorator(target, key); break;
            case "object": value = decorator(target, key, value) || value; break;
        }
    }
    return value;
};

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์„œ๋ช…:

์œ ํšจํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  1. ์•„๋ž˜์— ์„ค๋ช…๋œ ๋Œ€๋กœ Decorator ์œ ํ˜•(ClassDecorator | PropertyDecorator | MethodDecorator | ParameterDecorator) ์ค‘ ํ•˜๋‚˜์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  2. ๋ฐ์ฝ”๋ ˆ์ดํŒ…๋œ ๊ฐ’์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ’(ํด๋ž˜์Šค ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๋ฐ ๋ฉ”์„œ๋“œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์˜ ๊ฒฝ์šฐ)์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;
declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;
declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
declare type ParameterDecorator = (target: Function, propertyKey: string | symbol, parameterIndex: number) => void;

๋…ธํŠธ:

  • ํ•จ์ˆ˜ ์„ ์–ธ์„ ์žฅ์‹ํ•˜๋Š” ๊ฒƒ์€ ์˜๋ฏธ๋ก ์˜ ์ค‘์š”ํ•œ ๋ณ€๊ฒฝ์ธ ๋ฒ”์œ„์˜ ๋งจ ์œ„๋กœ ํ•จ์ˆ˜๋ฅผ ๋Œ์–ด์˜ฌ๋ฆฌ๋Š” ๊ฒƒ์„ ์ฐจ๋‹จํ•˜๋ฏ€๋กœ ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๋ฐ์ฝ”๋ ˆ์ด์…˜ ํ•จ์ˆ˜ ํ‘œํ˜„์‹ ๋ฐ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. var x = dec(function () { }); ๋กœ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ธฐ๋Šฅ์„ ์ ์šฉํ•ด๋„ ๋™์ผํ•œ ํšจ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ธฐ๋Šฅ ํ˜•์‹ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์žฅ์‹ํ•˜๋Š” ๊ฒƒ์€ ํ˜„์žฌ ES7 ์ œ์•ˆ์˜ ์ผ๋ถ€๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.
  • ES3๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•  ๋•Œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
Committed ES Next Fixed Suggestion

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๊ธฐ๋Šฅ ์žฅ์‹์€ ๋ฌผ๋ก  ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
์ฝ”๋“œ์—์„œ ๋‹ค๋ฅธ ๊ฐœ์ฒด๋ฅผ ์žฅ์‹ํ•  ๊ณ„ํš๋„ ์žˆ์Šต๋‹ˆ๊นŒ?

๋ชจ๋“  139 ๋Œ“๊ธ€

์‚ฌ์–‘์— ๋Œ€ํ•ด ์ œ๊ฐ€ ์ดํ•ดํ•œ ๋ฐ”์— ๋”ฐ๋ฅด๋ฉด ์‹ค๋ก€ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

<strong i="6">@F</strong>
function test() {
}

๋‚ด ๋ง์ด ๋งž์•„?

์œ ํ˜• ์ง๋ ฌํ™”๋Š” ๋‚˜๋จธ์ง€ ์ธ์ˆ˜์™€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

@F()  
class Foo {  
    constructor(...args: string[]) {  
    }  
}  

function F(<strong i="6">@paramterTypes</strong> types?: Function[]) {  
    return function (target) {  
        target.paramterTypes = types; // ???  
    }  
}

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ถฉ๋ถ„ํžˆ ๊ฐ„๋‹จํ•ด ๋ณด์ด์ง€๋งŒ, ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์„ ์–ธํ•˜๋Š” ์„น์…˜์ด ํ˜ผ๋ž€์Šค๋Ÿฝ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค. C.4์—์„œ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์— @decorator ์ฃผ์„์„ ๋‹ฌ์•„์•ผ ํ•œ๋‹ค๊ณ  ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ ์ด๋Ÿฌํ•œ ์ผ์ด ์ผ์–ด๋‚˜๋Š” ๊ฒƒ์„ ๋ณด์—ฌ์ฃผ๋Š” ์˜ˆ์ œ๋Š” ๋‹จ ํ•˜๋‚˜๋„ ์—†์Šต๋‹ˆ๋‹ค.

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒฉํ† ๋ฆฌ๋Š” B์— ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๊นŒ?

CoverMemberExpressionSquareBracketsAndComputedPropertyName์˜ ํ•ด์„์„ ๊ตฌ์ฒดํ™”ํ•˜๋Š” ๊ทœ์น™์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๋‚˜๋Š” ๋งŽ์€ ํƒ€์ดํ•‘์ด ๋‹ค์–‘ํ•œ ์ง€์ ์—์„œ Function | Object ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•„์ฐจ๋ ธ์ง€๋งŒ, ์ด๊ฒƒ๋“ค์€ ํƒ€์ž… ์ฒดํฌ ์‹œ๊ฐ„์— Object๋กœ ๋ณ€์งˆ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฑฐ๊ธฐ์— Function์ด ์žˆ๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๋‚˜๋Š” DecoratorFunction ๋Œ€ โ€‹โ€‹DecoratorFactory๋ผ๋Š” ์šฉ์–ด์— ๋Œ€ํ•ด ๋ฏธ์ณค์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ €๋Š” Generator์™€ GeneratorFunction์ด ์žˆ๋Š” ์ œ๋„ˆ๋ ˆ์ดํ„ฐ์˜ ๋ช…๋ช…๋ฒ•์„ ๋”ฐ๋ฅด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ด ์ฒด๊ณ„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ DecoratorFunction์˜ ์ด๋ฆ„์„ Decorator๋กœ, DecoratorFactory๋ฅผ DecoratorFunction์œผ๋กœ ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

์žฅ์‹ ์ˆ˜์ถœ์˜ ๊ฒฝ์šฐ [lookahead โ‰  @] ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? HoistableDeclaration ๋ฐ ClassDeclaration์ด ์‹ค์ œ๋กœ @ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์ด๊ฒƒ์€ #1557์˜ ์ค‘๋ณต์ž…๋‹ˆ๋‹ค.

#1557์ด ๋‹ค๋ฅธ ๋””์ž์ธ์„ ์œ„ํ•œ ๊ฒƒ์ด๋ฏ€๋กœ ์‹ค์ œ๋กœ ์†์ž„์ˆ˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋Š” ํ˜„์žฌ ๊ตฌํ˜„๋˜๊ณ  ์žˆ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๋””์ž์ธ์— ๋Œ€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚ด ์‹ค์ˆ˜.

ํ•จ์ˆ˜ ํ‘œํ˜„์˜ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์˜ ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

@F("color") <strong i="6">@G</strong> 
function myFunc() {
   doSomething();
}

๋ณ€ํ™˜:

var _t = function() {
   doSomething();
}
_t = F("color")(_t = G(_t) || _t) || _t;  

function myFunc() {
  return _t.apply(this, arguments)
}

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ๋ฐ”๋กœ์žก์•„์•ผ ํ•˜๋Š” ๊ฒƒ์€ ์•ฝ๊ฐ„ ๊ท€์ฐฎ์Šต๋‹ˆ๋‹ค.

const myFunc = function () {}

๋‹น์‹ ์€ ๋Š์Šจํ•œ ๊ฒŒ์–‘, ๊ทธ๋ฆฌ๊ณ  function.name

PR #2399์— ์ถ”๊ฐ€๋œ ๊ตฌํ˜„

์—…๋ฐ์ดํŠธ: ์ œ์•ˆ์ด ์—…๋ฐ์ดํŠธ๋˜๊ณ  @wycats ES7 JavaScript ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์— ๋Œ€ํ•œ ๋งํฌ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•™๊ธ‰๋งŒ์˜ ์ผ์ด ๋˜์–ด ์•ˆํƒ€๊น์Šต๋‹ˆ๋‹ค...
๋˜ํ•œ ์•ฐ๋น„์–ธํŠธ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚ฌ์Šต๋‹ˆ๊นŒ?

๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ๊ท€ํ•˜์˜ ์ œ์•ˆ๊ณผ ํ•จ๊ป˜ @fdecampredon ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹๊ฒŒ์–‘์„ ์žƒ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@JsonFreeman ์™œ? ํŒŒ์ผ ๋งจ ์œ„์— _t ๋ฅผ ์‚ฝ์ž…ํ•˜๋ฉด?

import something from 'something';

myFunc(something.something());

@F("color") <strong i="8">@G</strong> 
function myFunc() {
  doSomething()
}
import something from 'something';

var _t = function() {
   doSomething();
}
_t = F("color")(_t = G(_t) || _t) || _t;  

myFunc(something.something());

function myFunc() {
  return _t.apply(this, arguments)
}

๋˜ํ•œ ๋‚ด ์ œ์•ˆ์— ๋งŽ์€ ๋ฌธ์ œ๊ฐ€ ์žˆ๋”๋ผ๋„ ํ•จ์ˆ˜์— ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ (๋ณ€์ˆ˜ ํ• ๋‹น ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋„) ํ˜ธ์ด์ŠคํŒ…์„ ์žƒ์„ ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ์ง„์ง€ํ•˜๊ฒŒ ์›ํ•ฉ๋‹ˆ๋‹ค.
์ด ์š”์ง€ ์™€ ๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ํ•จ์ˆ˜์™€ ํด๋ž˜์Šค ๋ชจ๋‘์— ๋Œ€ํ•ด ๊ฝค ์ข‹์€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์‚ฌ์šฉ ์‚ฌ๋ก€๋กœ ๋ณด์ž…๋‹ˆ๋‹ค(ํŠนํžˆ ์—ฌ์ „ํžˆ ๋ฒ”์œ„์— ์žˆ๋Š” ๊ฒฝ์šฐ ์ฃผ๋ณ€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์™€ ๊ฒฐํ•ฉ๋จ)

@fdecampredon ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ํ‘œํ˜„ ์ž์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ์—๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜ˆ

myFunc();  // assumes function declaration is hoisted

var dec = (t) => t; // defininig a decorator

<strong i="7">@dec</strong>
function myFunc() {}

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์˜ ํ•จ์ˆ˜ ์„ ์–ธ๊ณผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํ˜ธ์ด์ŠคํŠธํ•˜๋ฉด ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ๊นจ์ง‘๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ์„ ์–ธ๋งŒ ํ˜ธ์ด์ŠคํŠธํ•˜๊ณ  ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ํ˜ธ์ด์ŠคํŠธํ•˜์ง€ ์•Š์œผ๋ฉด ์žฅ์‹๋˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ํ•จ์ˆ˜๋ฅผ ๋ชฉ๊ฒฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ๋งค๋ ฅ์ ์ธ ์†”๋ฃจ์…˜์ด ์—†์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ES6์—์„œ ํ‘œํ˜„์‹์ธ ํด๋ž˜์Šค ์„ ์–ธ ํ™•์žฅ ์ ˆ๊ณผ ๋™์ผํ•œ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ๋Š” ํด๋ž˜์Šค ์„ ์–ธ์ด ์•„๋‹ˆ๋ผ ๊ธฐํ˜ธ(var ์„ ์–ธ๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ ํ•จ์ˆ˜ ์„ ์–ธ์€ ์•„๋‹˜)๋งŒ ๋Œ์–ด์˜ฌ๋ฆฌ๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

@mhegazy ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ๊ธฐ๋Šฅ ๋ถ€๋ถ„์ด ์›๋ž˜ @jonahandturner ์ œ์•ˆ์„ ์™„์ „ํžˆ ํฌ๊ธฐํ•œ ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

decorated function declarations cannot be hoisted to the containing scope

ํ˜ธ์ด์ŠคํŒ…์„ ์žƒ๋Š” ๊ฒƒ์€ ํ™•์‹คํžˆ ๋‹จ์ ์ด์ง€๋งŒ ๋‹ค๋ฅธ ๊ตฌ์„ฑ์— ๋Œ€ํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ์žˆ์„ ๋•Œ ํด๋ž˜์Šค ์ „์šฉ ๊ธฐ๋Šฅ์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ์†์ƒ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค.

์›ํ•˜๋Š” ์ œ์•ฝ ์กฐ๊ฑด ์ง‘ํ•ฉ์ด ์˜๋ฏธํ•˜๋Š” ๋ฐ”๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  • ์žฅ์‹๋œ ๊ธฐ๋Šฅ์€ ํ˜ธ์ด์ŠคํŠธ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ํ•จ์ˆ˜๋Š” ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ฆ‰์‹œ ๋ฐ์ฝ”๋ ˆ์ดํŠธ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ํ˜ธ์ด์ŠคํŠธ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ์ ์šฉ๋˜๊ธฐ ์ „์— ์ •์˜๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ •์˜ ์ž์ฒด(๋˜๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํ‘œํ˜„์‹์—์„œ ์ฐธ์กฐํ•˜๋Š” ๋ชจ๋“  ์—”ํ‹ฐํ‹ฐ)๋Š” ํ˜ธ์ด์ŠคํŠธ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํ‘œํ˜„์‹์€ ์–ดํœ˜์ ์œผ๋กœ ์ ์šฉ๋œ ์œ„์น˜์—์„œ ํ‰๊ฐ€๋˜๋ฏ€๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํ˜ธ์ด์ŠคํŒ…ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ด์— ๋Œ€ํ•ด ๋‚ด๊ฐ€ ๋ณผ ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ํ•ด๊ฒฐ์ฑ…์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์˜ ๊ฒฝ์šฐ @identifier ํ˜•์‹๋งŒ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์™ผ์† ํ‘œํ˜„์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์‹๋ณ„์ž๋Š” ํ•จ์ˆ˜ ์„ ์–ธ(๋ฐ์ฝ”๋ ˆ์ดํŠธ๋œ ํ•จ์ˆ˜ ํฌํ•จ)์— ๋Œ€ํ•œ ์ง์ ‘ ์ฐธ์กฐ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฒ”์œ„์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ชจ๋“  ํ•จ์ˆ˜ ์žฅ์‹์€ ์ ์šฉ๋œ ์ˆœ์„œ๋Œ€๋กœ ๋ฒ”์œ„์˜ ๋งจ ์œ„์—์„œ ๋ฐฉ์ถœ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ˜ธ์ด์ŠคํŒ… ๊ทœ์น™์„ ๊นจ๋Š” ๋ฌธ์ œ๋Š” ๊ทธ๊ฒƒ์ด ๋†€๋ž๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ž ์‹œ ๋™์•ˆ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒฝ์šฐ ํ•จ์ˆ˜ ์„ ์–ธ์ด ์‚ฌ์ „์ ์œผ๋กœ ์„ ์–ธ๋˜๊ธฐ ์ „์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ๊ฒ‰๋ณด๊ธฐ์— ๋‹จ์ˆœํ•œ ๊ตฌ๋ฌธ ํ‘œ์‹œ์ž(๋ฐ์ฝ”๋ ˆ์ดํ„ฐ)๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ํ•จ์ˆ˜ ์„ ์–ธ์˜ ๊ธฐ๋ณธ ํŠน์„ฑ์„ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

ES7 ์ œ์•ˆ์€ ์•„์ง ์ดˆ๊ธฐ ๋‹จ๊ณ„์ด๋ฏ€๋กœ ๋ฐœ์ „ํ•˜๊ณ  ํ™•์žฅํ•  ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ตœ์ข… ์ œ์•ˆ์—๋Š” ์–ด๋–ค ํ˜•ํƒœ๋กœ๋“  ๊ธฐ๋Šฅ์ด ํฌํ•จ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ทธ๊ฒƒ๋“ค์„ ๋“ค์–ด ์˜ฌ๋ ค์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ๊ธฐ๋Šฅ์— ํ—ˆ์šฉํ•˜๋Š” ์œ ์ผํ•œ ์žฅ์‹์€ ํ™•์‹คํžˆ ๊ทธ ์ž์ฒด๋กœ ๊ฒŒ์–‘๋˜๋Š” ์žฅ์‹์ด๋ผ๊ณ  ๋งํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ํ•จ์ˆ˜ ์„ ์–ธ์„ ์ฐธ์กฐํ•˜๋Š” ์‹๋ณ„์ž์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์—ฌ๊ธฐ์— ๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์žฅ์‹๋œ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ๋™์‹œ์— ํ˜ธ์ด์ŠคํŠธํ•˜๊ณ  ์žฅ์‹๋˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ๊ด€์ฐฐ๋˜์ง€ ์•Š๋„๋ก ํ•˜๋Š” ๊ฒƒ์€ ์‹ค์ œ๋กœ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ฃผ๊ธฐ์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<strong i="7">@dec1</strong>
function dec2(target: Function) {
   // Do stuff
}

<strong i="8">@dec2</strong>
function dec1(target: Function) {
   // Do stuff
}

๋‘ ๊ธฐ๋Šฅ์ด ๋ชจ๋‘ ํ˜ธ์ด์ŠคํŠธ๋˜์–ด๋„ ์–ด๋Š ๊ฒƒ์ด ๋จผ์ € ์žฅ์‹๋ฉ๋‹ˆ๊นŒ? dec2๊ฐ€ ๋จผ์ € ์žฅ์‹๋˜๋ฉด dec2์— ์ ์šฉ๋  ๋•Œ๊นŒ์ง€ dec1 ์ž์ฒด๊ฐ€ ์žฅ์‹๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ ์ค‘์—์„œ ์„ ํƒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ๊ธฐ๋Šฅ์ด ํ˜ธ์ด์ŠคํŒ…๋˜์ง€ ์•Š์Œ
  • ์žฅ์‹๋˜์ง€ ์•Š์€ ํ•จ์ˆ˜๋Š” ํ˜ธ์ด์ŠคํŠธ๋˜์ง€๋งŒ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์€ ํ•จ๊ป˜ ํ˜ธ์ด์ŠคํŒ…๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด ์ค‘ ์–ด๋Š ๊ฒƒ๋„ ์ข‹์•„ํ•˜์ง€ ์•Š์ง€๋งŒ, ๋‹ค๋ฅธ ์–ด๋–ค ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ JS ์ œ์•ˆ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์—”์ง„์€ ํ‘œํ˜„์‹์ด ํ•จ์ˆ˜ ์„ ์–ธ์„ ์ฐธ์กฐํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์•Œ์ง€ ๋ชปํ•˜์ง€๋งŒ ์ •์  ๋ถ„์„์„ ํ†ตํ•ด ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฑธ ๊ณ ๋ คํ•˜์„ธ์š”:

<strong i="6">@dec1</strong>
function dec2(target: Function) {
   // Do stuff
}

dec2 = undefined;

<strong i="7">@dec2</strong>
function dec1(target: Function) {
   // Do stuff
}

์œผ์•…! Javascript๋Š” ๋” ์ด์ƒ ๋‹จ์ˆœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. :-)

_expressions_ ๊ธฐ๋Šฅ์—์„œ๋งŒ ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ์ด ๋” ์‰ฌ์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

const foo = <strong i="6">@decorator</strong> () => {
    // ...   
}
const bar = <strong i="7">@decorator</strong> function() {
    // ...
}

ํ•จ์ˆ˜ ํ‘œํ˜„์‹ ๋˜๋Š” ๋žŒ๋‹ค๊ฐ€ ํ˜ธ์ด์ŠคํŠธ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

typescript 1.5.0-alpha์˜ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์— ์ด์™€ ๊ฐ™์€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@dec1({key1: value1, key2, value2})
function dec2(target: Function) {
   // Do stuff
}

์‹ ๊ฒฝ์“ฐ์ง€ ๋งˆ์„ธ์š”. ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ค์ œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ธฐ๋Šฅ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํŒฉํ† ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”.

์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฌธ์ž์—ด ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์žˆ๋Š” ํด๋ž˜์Šค ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

function decoratorWithString(param: string) { // Decorator factory
    return function(target) { // Actual decorator
        // Do stuff with target and string parameter
    }
}

// Usage
@decoratorWithString('foobar')
class Foo {

}

์ธ์‚ฌ๋ง.

์ƒ์„ฑ์ž์— ์„ ์–ธ๋œ ์œ ํ˜•์„ ์„ ํƒํ•˜๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„ ๋‚ด๋ ค๊ณ  ๋…ธ๋ ฅ ์ค‘์ž…๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์— ๋‚ด๊ฐ€ ํ•˜๋ ค๊ณ  ํ•˜๋Š” ๊ฒƒ์„ ์„ค๋ช…ํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ์ฝ”๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Š” ๊ณ ์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ž˜์Šค D์˜ ์ƒ์„ฑ์ž ์„ ์–ธ์— ์‘๋‹ตํ•˜๋Š” ๋ฐ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

class A {
  public message = "identity: class A";
}

class B {
  public message = "identity: class B";
}

<strong i="8">@decoTest</strong>
class D {
  static metadata:Array<Function> = [];
  constructor(a: A, b: B) {
  }
}
describe("decorators", function() {
  it("should inject constructor types", function() {
    var d = new D(new A(), new B());
    expect(D.metadata.length).toBe(2);
  });
});


function decoTest<T>(target: T, ...rest) {
  target["metadata"].push(A, B); // how do i get this based on constructor ???
  return target;
}

์œ ํ˜• ์ •๋ณด๊ฐ€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ธฐ๋Šฅ์˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚ฉ๋‹ˆ๋‹ค.
๊ฐ ๋งค๊ฐœ๋ณ€์ˆ˜์— ParameterDecorator๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ์ •๋ณด๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ParameterDecorator์˜ ํƒ€์ดํ•‘์ด๋‚˜ ๊ตฌํ˜„์ด ์ •ํ™•ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํƒ€์ดํ•‘์—์„œ ๋Œ€์ƒ์€ ํ•จ์ˆ˜์ด์ง€๋งŒ typescript๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋™์•ˆ์—๋Š” ํ”„๋กœํ† ํƒ€์ž… ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.
์˜ฌ๋ฐ”๋ฅธ ์œ ํ˜•์„ ์–ป์œผ๋ ค๋ฉด ๋Œ€์ƒ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์บ์ŠคํŒ…ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

function MyParameterDecorator (_target: Function, methodName: string, index: number) {
    const target = <InterfaceForMyUseCase><anyt>_target;
    // do stuff
}

๋Œ€์‹ ์—:

function MyParameterDecorator (target: InterfaceForMyUseCase, methodName: string, index: number) {
    // do stuff
}

์™€์šฐ - ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ทœ์น™ !!!!!!!!!!!!!! ์ด ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค

๋‹ค์Œ์€ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•œ ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค.

LOG: 'injectMe:'
LOG: '  type: class A'
LOG: '  type: class B'
LOG: '  some key'

๊ทธ๋ฆฌ๊ณ  ์ฝ”๋“œ :

module ParameterDecorators {
  class A {
    static typeName:string = "type: class A";
    public instanceTypeName = "instance: class A";
  }

  class B {
    static typeName:string = "type: class B";
    public instanceTypeName = "instance: class B";
  }

  @injectTest(A, B, "some key")
  class C {
    static injectMe: Array<any> = [];
    constructor(a: A, b: B) {
    }
  }

  function injectTest(...rest) {
    return function(target): void {
      target["injectMe"] = rest;
    }
  }

  describe("decorators", function() {
    it("should inject dependency-injection keys", function() {
      var c = new C(new A(), new B());
      console.log("injectMe:");
      for (let parm of C.injectMe) {
        if (typeof(parm) === "function") {
          console.log("\t" + parm["typeName"]);
        } else {
          console.log("\t" + parm)
        }
      }
    });
  });
}

๋‚˜๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ธฐ๋ฐ˜ API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ต์Šคํ”„๋ ˆ์Šค(๊ทธ๋Ÿฌ๋‚˜ ๋ชจ๋“  ์›น ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ง€์›๋  ์ˆ˜ ์žˆ๊ณ  ์–ด๋Œ‘ํ„ฐ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์ •์˜๋จ) ์ฃผ์œ„์— ๋ž˜ํผ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. https://github.com/cybrown/web-decorators

ClassDecorator, ParameterDecorator ๋ฐ MethodDecorator๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

@cybrown ์ง€๊ธˆ ๋งˆ์Šคํ„ฐ์— ์žˆ๋Š” #2635์—์„œ ParameterDecorator ์— ๋Œ€ํ•œ ์„œ๋ช…์„ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค.

@rbuckton ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

ParameterDecorator์—์„œ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์ด๋ฆ„์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
์ด๊ฒƒ์€ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์ด๋ฆ„์ด ParameterDecorator์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜์˜ ์ ˆ๋ฐ˜์ด ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ฒŒ๋‹ค๊ฐ€, ๊ทธ๊ฒƒ์€ ์ถ•์†Œ์ž์— ์˜ํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜ ์ด๋ฆ„ ๋งน๊ธ€๋ง์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์„ ์„ฑ์ทจํ•˜๋„๋ก ์š”์ฒญ๋ฐ›์•˜๋‹ค:

@inject(A, B, "some key")
  class C {
    static injectMe: Array<any> = [];
    constructor(a: A, b: B) {
    }
  }

  function inject(...rest) {
    return function(target): void {
      target["inject"] = rest;
    }
  }

๊ทธ๋Ÿฌ๋‚˜ ์ฃผ์ž… ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์—์„œ ํ‚ค๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š๊ณ  ๋Œ€์‹  ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ๋‹ค์Œ ์ค„์„ ๋”ฐ๋ผ ์ƒ์„ฑ์ž์˜ ํด๋ž˜์Šค ํ•จ์ˆ˜๋ฅผ ์ž๋™์œผ๋กœ ์„ ํƒํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

inject(<strong i="9">@parameterTypes</strong> types:Function[]){ ... }

@jonahandturner๊ฐ€ ์—ฌ๊ธฐ์—์„œ ์„ค๋ช…ํ•˜๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ๊ณ 

@cmchaelgraham ์˜ˆ, ๋Ÿฐํƒ€์ž„ ์œ ํ˜• ์ •๋ณด(AtScript์— ์„ค๋ช…๋œ rtti)๊ฐ€ ์žˆ์œผ๋ฉด ๋‚ด๋ถ€ ๊ฒ€์‚ฌ์™€ ๊ฐ™์ด ์™„์ „ํžˆ ๋ถ„๋ฆฌ๋œ ๊ธฐ๋Šฅ์—์„œ๋„ ๊ทธ๋Ÿฐ ์ข…๋ฅ˜์˜ ์‚ฌ์šฉ์— ๋งค์šฐ ์ข‹์Šต๋‹ˆ๋‹ค.

@cmchaelgraham ์€ https://github.com/Microsoft/TypeScript/pull/2589๋ฅผ ์‚ดํŽด๋ณด์‹ญ์‹œ์˜ค.

@cmicaelgraham ์šฐ๋ฆฌ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•  ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ API ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ES7์— ๋Œ€ํ•œ ์ œ์•ˆ์„ ์ž‘์—… ์ค‘์ž…๋‹ˆ๋‹ค. #2589๋Š” ํ•ด๋‹น ์ œ์•ˆ์— ๋Œ€ํ•œ ์‹คํ—˜์  ์ง€์›์„ ์ถ”๊ฐ€ํ•˜์ง€๋งŒ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์œผ๋ ค๋ฉด ๋ณ„๋„์˜ ํด๋ฆฌํ•„ ์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@rbuckton @cmichaelgraham ์›๋ž˜ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๋Œ€์ƒ์— ๋”ฐ๋ผ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์— ์œ ํ˜•์„ ์ฃผ์ž…ํ•˜๋„๋ก ์ปดํŒŒ์ผ๋Ÿฌ์— ์ง€์‹œํ•˜๋Š” ํŠน์ˆ˜ํ•œ TypeScript ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์œ„ํ•œ ๋””์ž์ธ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด @parameterTypes ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋” ์ผ๋ฐ˜์ ์ธ ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ API๋ฅผ ์œ„ํ•ด ๊ทธ ๊ธฐ๋Šฅ์ด ์ œ๊ฑฐ๋˜๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์ด ๋งž์Šต๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด ์ง€์›ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

TypeScript์™€ ๊ด€๋ จ๋œ ์ƒํƒœ์— ๋Œ€ํ•ด ์กฐ๊ธˆ ๋ง์”€ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? 1.5 ์ถœ์‹œ ์˜ˆ์ •์ธ๊ฐ€์š”? ๊ทธ๋ ‡๋‹ค๋ฉด ์ปดํŒŒ์ผ๋Ÿฌ ์˜ต์…˜์€ ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ์Šต๋‹ˆ๊นŒ? ์œ ์šฉํ•œ ํ•œ ๊ฐ€์ง€๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ƒ์„ฑ์ž ์„œ๋ช…์— ๋Œ€ํ•ด์„œ๋งŒ ํ˜•์‹ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@EisenbergEffect ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” 1.5์˜ ์ผ๋ถ€์ด๋ฉฐ ์ตœ์‹  ๋ฆด๋ฆฌ์Šค 1.5-alpha์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ ์ง€์›์— ๊ด€ํ•ด์„œ. @paramtypes ๋Œ€ํ•œ ์›๋ž˜ ์ œ์•ˆ ์ดํ›„ ๋””์ž์ธ์ด ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๋””์ž์ธ์€ Reflect.metada ์ œ์•ˆ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ž‘๋™ ๋ฐฉ์‹์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ #2589๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”. ๋˜ํ•œ @rbuckton ์—๋Š” https://github.com/rbuckton/reflectDecorators ์—์„œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ pollyfill์ด ์žˆ์Šต๋‹ˆ๋‹ค.

@mhegazy ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค . ์—ฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค: http://blog.durandal.io/2015/04/09/aurelia-update-with-decorators-ie9-and-more/ :smile:

๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ œ์•ˆ์— ๋Œ€ํ•ด์„œ๋„ ์ž˜ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ํ”ผ๋“œ๋ฐฑ์„ ํ•ด์™”์Šต๋‹ˆ๋‹ค. ์›๋ž˜ @parameterTypes ์•„์ด๋””์–ด๊ฐ€ ์ œ๊ฑฐ๋˜๋Š”์ง€ ์•Œ๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

๊ณต์œ ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค @EisenbergEffect . :+1:

์˜ˆ. @paramtypes ์˜ ์œ ์ผํ•œ ๋ฌธ์ œ๋Š” ๋ฐฉ์ถœ์ด ์œ ํ˜• ์‹œ์Šคํ…œ์— ์˜ํ•ด ์ง€์‹œ๋˜๊ณ  ์ „์—ญ ํ”„๋กœ๊ทธ๋žจ ์ •๋ณด๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‹จ์ผ ๋ชจ๋“ˆ ๋ณ€ํ™˜์— ๋Œ€ํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค(#2499 ์ฐธ์กฐ). ๋‹ค๋ฅธ ์˜ต์…˜์€ ์ฝœ ์‚ฌ์ดํŠธ์— ๋„ฃ๋Š” ๊ฒƒ์ธ๋ฐ, ์ด๋Š” ์ž‘์„ฑ์ž ๋Œ€์‹  ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋งŽ์€ ์ž‘์—…์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” ๋‹ค์‹œ ๊ธฐ๋ณธ์œผ๋กœ ๋Œ์•„๊ฐ€์„œ Reflect.metadata ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

์ œ์•ˆ์˜ ์ด์ „ ๋ฒ„์ „๋„ ๋ดค๋‹ค๋ฉด ๊ฐ™์€ ์ด์œ ๋กœ ์•ฐ๋น„์–ธํŠธ/๋””์ž์ธ ํƒ€์ž„ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ œ๊ฑฐํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ช…ํ™•ํžˆ ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฒƒ์ด ์ดํ•ด๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. Reflect ๊ธฐ๋ฐ˜ ์ ‘๊ทผ ๋ฐฉ์‹์ด 1.5์— ๋„์ž…๋ ์ง€ ์—ฌ๋ถ€์— ๋Œ€ํ•œ ์•„์ด๋””์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

์˜ˆ. ํ˜„์žฌ ๋งˆ์Šคํ„ฐ์— ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ฆด๋ฆฌ์Šค์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ์‹คํ—˜ ํ”Œ๋ž˜๊ทธ --emitDecoratorMetadata ์‚ฌ์šฉํ•˜๋Š” ์˜ตํŠธ์ธ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํŒ…๋œ ์—”ํ„ฐํ‹ฐ์—๋งŒ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

"๋ฐ์ฝ”๋ ˆ์ดํŒ…๋œ ์—”ํ„ฐํ‹ฐ์—๋งŒ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค." ๊ทธ ์•„์ด๋””์–ด๋ฅผ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ํŠน๋ณ„ํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ์ฐธ์—ฌํ•ฉ๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ์–ด๋–ค ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์™€ ํ•จ๊ป˜ ๋ฌด์—‡์ด๋“  ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๊นŒ? ์ฆ‰, ๊ฐœ๋ฐœ์ž๊ฐ€ Aurelia์˜ inject ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๊นŒ?

๊ฐœ๋ฐœ์ž๊ฐ€ Aurelia์˜ ์ธ์ ํŠธ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๊นŒ?

์˜ˆ.

๋‚ด๊ฐ€ ์˜๋ฏธํ•˜๋Š” ๋ฐ”๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

<strong i="9">@inject</strong>
class Foo {
    constructor(a: number, b: string) {}
}

class Bar {
    constructor(a: number, b: string) {}
}

ํ•จ๊ป˜ --emitDecoratorMetadata (์ฆ‰, ํ˜ธ์ถœ์— ์ž…๋ ฅ ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐฉ์ถœ ํ•  ์ปดํŒŒ์ผ๋Ÿฌ reflect.metadata('desing:paramtypes', [Number, String]) ์šฉ) Foo ์ด์ง€๋งŒ _not_ Bar .

๊ทธ๊ฒƒ์€ ์šฐ๋ฆฌ๋ฅผ ์œ„ํ•ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ฆด๋ฆฌ์Šค, ์•„๋งˆ๋„ ๋‹ค์Œ ์ฃผ์— Reflect.metadata API์— ๋Œ€ํ•œ ์ง€์›์„ ์ค€๋น„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์„ค๋ช… ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

๊ทธ๋ž˜์„œ ์ด๊ฒƒ์„ ์œ„ํ•ด ๋ฌด์—‡์„ ๋ฐฉ์ถœํ•ฉ๋‹ˆ๊นŒ?

``` ์–ธ์–ด=์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ
@์ฃผ์‚ฌ
ํด๋ž˜์Šค ํ‘ธ {
์ƒ์„ฑ์ž(a: A, b: B) {}
}

ํด๋ž˜์Šค ๋ฐ” {
์ƒ์„ฑ์ž(a: ์ˆซ์ž, b: B) {}
}

would it be (for Foo):

``` javascript
reflect.metadata('desing:paramtypes', [A, B])

@cmchaelgraham ์˜ˆ, ๋Œ€๋žต์ ์œผ๋กœ ์ƒ์„ฑ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฏธ์นœ ๋ฉ‹์ ธ!!!!

gulp -typescript ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ๊ตฌ์ถ• - (๋ฉ‹์ง„ @ivogabe)

gulpfile build-ts ๋ช…๋ น( emitDecoratorMetadata ์˜ต์…˜ ์ฐธ๊ณ ):

gulp.task('build-ts', function () {
    var tsResult = gulp.src([
        './views/*.ts',
        './typings/**/*.d.ts',
        './*.ts'
        ],
        {base: "."})
    .pipe(ts({
         typescript: require('typescript'),
         declarationFiles: false,
         noExternalResolve: true,
         target: "es5",
         module: "amd",
         emitDecoratorMetadata: true
    }));

    return merge([
        tsResult.dts.pipe(gulp.dest('.')),
        tsResult.js.pipe(gulp.dest('.'))
    ]);
});

app.ts ํšŒ์ „

import {inject} from 'aurelia-framework';
import {Router} from 'aurelia-router';
import 'bootstrap';
import 'bootstrap/css/bootstrap.css!';

@inject(Router)
export class App {
  public router;
  constructor(router:Router) {
    this.router = router;
    this.router.configure(config => {
      config.title = 'Aurelia';
      config.map([
        { route: ['','welcome'],  moduleId: './welcome',      nav: true, title:'Welcome' },
        { route: 'flickr',        moduleId: './flickr',       nav: true },
        { route: 'child-router',  moduleId: './child-router', nav: true, title:'Child Router' }
      ]);
    });
  }
}

app.js

var __decorate = this.__decorate || (typeof Reflect === "object" && Reflect.decorate) || function (decorators, target, key, desc) {
    switch (arguments.length) {
        case 2: return decorators.reduceRight(function(o, d) { return (d && d(o)) || o; }, target);
        case 3: return decorators.reduceRight(function(o, d) { return (d && d(target, key)), void 0; }, void 0);
        case 4: return decorators.reduceRight(function(o, d) { return (d && d(target, key, o)) || o; }, desc);
    }
};
var __metadata = this.__metadata || (typeof Reflect === "object" && Reflect.metadata) || function () { };
define(["require", "exports", 'aurelia-framework', 'aurelia-router', 'bootstrap', 'bootstrap/css/bootstrap.css!'], function (require, exports, aurelia_framework_1, aurelia_router_1, , ) {
    var App = (function () {
        function App(router) {
            this.router = router;
            this.router.configure(function (config) {
                config.title = 'Aurelia';
                config.map([
                    { route: ['', 'welcome'], moduleId: './welcome', nav: true, title: 'Welcome' },
                    { route: 'flickr', moduleId: './flickr', nav: true },
                    { route: 'child-router', moduleId: './child-router', nav: true, title: 'Child Router' }
                ]);
            });
        }
        App = __decorate([
            aurelia_framework_1.inject(aurelia_router_1.Router), 
            __metadata('design:paramtypes', [aurelia_router_1.Router])
        ], App);
        return App;
    })();
    exports.App = App;
});

ํŠนํžˆ ํฅ๋ฏธ๋กœ์šด ๊ฒƒ์€ ์ƒ์„ฑ์ž ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ๋ฐฉ์ถœ๋œ ์œ ํ˜• ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค.

        App = __decorate([
            aurelia_framework_1.inject(aurelia_router_1.Router), 
            __metadata('design:paramtypes', [aurelia_router_1.Router])
        ], App);

๋”ฐ๋ผ์„œ ์ด๋ก ์ƒ์œผ๋กœ๋Š” ์ฃผ์ž… ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•˜์—ฌ ์ฃผ์ž…์—์„œ ์ง€์ •ํ•˜์ง€ ์•Š๊ณ  ์ ์ ˆํ•œ ํด๋ž˜์Šค๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋Œ€์‹  ์ƒ์„ฑ์ž์—์„œ ์œ ํ˜•์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. :)

@cmhichaelgraham ์šฐ๋ฆฌ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ ๋„ ์ด๊ฒƒ์„ ์‰ฝ๊ฒŒ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Aurelia์˜ DI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—๋Š” container.addParameterInfoLocator ํ›„ํฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜•์‹์„ ์ทจํ•˜๊ณ  ์ข…์†์„ฑ์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ฆด๋ฆฌ์Šค(๋‹ค์Œ ์ฃผ)์—์„œ๋Š” ์ด๊ฒƒ์„ ํ•ต์‹ฌ ๊ตฌ์„ฑ์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ TypeScript ๊ฐœ๋ฐœ์ž๊ฐ€ ์‰ฝ๊ฒŒ ์ผค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ์ฃผ ์ถœ์‹œ์— ๋„ฃ์—ˆ์–ด์•ผ ํ–ˆ๋Š”๋ฐ ์ด๊ฒŒ ๋ณ€๊ฒฝ๋œ ์ค„์€ ์•„์ง ๋ชฐ๋ž์Šต๋‹ˆ๋‹ค.

@EisenbergEffect ๋ธŒ๋ฆด๋ฆฌ์–ธํŠธ !! :+1:

๋‚˜๋Š” ์ฃผ์„์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐœ์ฒด์˜ ์†์„ฑ์„ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์œผ๋กœ ํ‘œ์‹œํ–ˆ๋Š”๋ฐ, ์ด๋Š” ๊ธฐ๋ณธ ๊ฐœ์ฒด๋ฅผ ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ๊ฐœ์ฒด๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค(๊ด€์‹ฌ ์žˆ๋Š” ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•ด https://github.com/mweststrate/MOBservable/commit/8cc7fc0e20c000db660037c8b5c9d944fe4155d9).

๊ทธ๋Ÿฌ๋‚˜ ํŠนํžˆ ์†์„ฑ์˜ ๊ฒฝ์šฐ ํด๋ž˜์Šค ์ž์ฒด์˜ ์ƒ์„ฑ์ž๊ฐ€ ์•„๋‹Œ ํ”„๋กœํ† ํƒ€์ž…์— ์ฃผ์„์„ ์ ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋‹ค์†Œ ๋ถ€์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋Š๊ปด์กŒ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์ดˆ๊ธฐ ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ธฐ๊ฐ€ ์–ด๋ ต๊ฑฐ๋‚˜ this ๋„ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. this ๋ฐ ๊ฐ’์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์„์ด ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š” ์‹ค์ œ ๋…ผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฒŒ๋‹ค๊ฐ€ ๊ต‰์žฅํ•œ ๊ธฐ๋Šฅ!

Metadata Reflection API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•œ ์†์„ฑ ์ข…์†์„ฑ ์ฃผ์ž…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
ํ•„์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ https://github.com/matjaz/property-DI/commit/2b4835e100b72d954b57d0e656ea524539ac17eb์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

๋ชจ๋“  ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ณด๋‹ค ๋จผ์ € ํ˜ธ์ถœ๋˜๋Š” ์ƒ์„ฑ๋œ ์ฝ”๋“œ์—์„œ __metadata ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ์•„๋‹ˆ์–ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? ํด๋ž˜์Šค์˜ ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•œ deocrator๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ์—ˆ์ง€๋งŒ __metadata('design:paramtypes', [TYPES....])๊ฐ€ ๋งˆ์ง€๋ง‰์œผ๋กœ ํ˜ธ์ถœ๋˜์—ˆ์œผ๋ฏ€๋กœ Reflect์—์„œ ์ด๋Ÿฌํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

@ufon ๋ณด๊ณ  ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๋ฌผ๋ก ์ž…๋‹ˆ๋‹ค. https://gist.github.com/ufo/5a2fa2481ac412117532

ํŽธ์ง‘ํ•˜๋‹ค:
๋‚ด ๋‚˜์œ, ๋‚ด ์ฝ”๋“œ์— ๋‹ค๋ฅธ ์‹ค์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ž˜์Šค ์ดˆ๊ธฐํ™” ํ›„์—๋„ ์œ ํ˜•์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

@ufon , ๋‚˜๋Š” ๊ทธ๋•Œ ๋‚ด๊ฐ€ ๋ฌธ์ œ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์‹ ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. __metadata๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๋ชฉ๋ก์˜ ๋งˆ์ง€๋ง‰ ํ•ญ๋ชฉ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ์ด๊ฒƒ์ด ๊ฐ€์žฅ ๋จผ์ € ์‹คํ–‰๋˜๊ณ , ํ™•์‹คํžˆ ์ฃผ์ž…์ด ์‹คํ–‰๋˜๊ธฐ ์ „์— ์‹คํ–‰๋œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.

    House = __decorate([
        inject_1.inject, 
        __metadata('design:paramtypes', [Floor, String])
    ], House);

์—ฌ๊ธฐ์„œ __decorate ์ •์˜๋Š” ๊ถŒํ•œ ์ถ•์†Œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์—ญ์ˆœ์œผ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

decorators.reduceRight(function(o, d) { return (d && d(o)) || o; }, target);

์ด๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ(ํ‘œํ˜„์‹)๊ฐ€ ์„ ์–ธ ์ˆœ์„œ๋Œ€๋กœ ํ‰๊ฐ€๋˜์ง€๋งŒ ์—ญ์ˆœ์œผ๋กœ ์‹คํ–‰๋˜์–ด ์™ธ๋ถ€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ๋‚ด๋ถ€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์˜ ๊ฒฐ๊ณผ๋ฅผ ์†Œ๋น„ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์‚ฌ์–‘๊ณผ ์ผ์น˜์‹œํ‚ค๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค, ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค: ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์ œ ์ฝ”๋“œ์— ๋‹ค๋ฅธ ์‹ค์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ž˜์Šค ์ดˆ๊ธฐํ™” ํ›„์—๋„ ์œ ํ˜•์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋‹น์‹ ์€ ๊ทธ๋“ค์„ ์–ด๋–ป๊ฒŒ ์ฟผ๋ฆฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? Reflect.metadata์— ๋Œ€ํ•œ pollyfill์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์š”์ ์— ์ถ”๊ฐ€ ...
Reflect.getMetadataKeys(ํ•˜์šฐ์Šค);
์ด ๊ฒฐ๊ณผ ๋นˆ ๋ฐฐ์—ด ..

์˜ˆ, 'reflect-metadata' ํŒจํ‚ค์ง€๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์„ ์žƒ์–ด๋ฒ„๋ฆฐ polyfill ๊ฐ™์€ ์™ธ๋ชจ, @rbuckton ๋‹น์‹ ์€ ์ข€ ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ›์•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ด...
ํ•„์š”๋Š” typescript์˜ ๋„์šฐ๋ฏธ ์ฝ”๋“œ ๋’ค์— ์ด๋™๋ฉ๋‹ˆ๋‹ค.

var __metadata = this.__metadata || (typeof Reflect === "object" && Reflect.metadata) || function () { };
require('reflect-metadata');

๋”ฐ๋ผ์„œ var __metadata๊ฐ€ ์ดˆ๊ธฐํ™”๋˜๋Š” ๋™์•ˆ ํด๋ฆฌํ•„์ด ์•„์ง ๋กœ๋“œ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ƒ์„ฑ๋œ ์ฝ”๋“œ ์ „์— ์ด๋Ÿฌํ•œ ์š”๊ตฌ ์‚ฌํ•ญ์„ ์–ป์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

ํŽธ์ง‘: ์š”์  ์—…๋ฐ์ดํŠธ

์Œ.. ๋” ํฐ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•ด ๊ธฐ๋ก๋œ ๋ฌธ์ œ #2811

๊ทธ๋•Œ๊นŒ์ง€๋Š” ๋‹ค๋ฅธ ๋ชจ๋“ˆ์— reflect-metadata ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค(๋‘ ๊ฐœ์˜ ํŒŒ์ผ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค).
https://github.com/matjaz/property-DI/ ์ฐธ์กฐ

๋ณ€์ˆ˜/์„ ํƒ์  ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๊ฐœ๋ฐœํ•˜๋Š” ๊ฒƒ์„ ์ƒ๋‹นํžˆ ์–ด๋ ต๊ฒŒ ๋งŒ๋“œ๋Š” ํ˜ธ์ถœ ๋ถˆ์ผ์น˜๊ฐ€ ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. ์˜ˆ๋กœ์„œ:

<strong i="6">@F</strong>
prop: number;

@F()
prop: number;

์ „์ž์—์„œ F๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜(target, propertyName, propertyDescriptor)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ˜ธ์ถœ๋˜๋Š” ๋ฐ˜๋ฉด ํ›„์ž์—์„œ๋Š” F๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ˜ธ์ถœ๋˜๋ฉฐ ๋ฐ˜ํ™˜๋œ ๋‚ด๋ถ€ ํ•จ์ˆ˜๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์†์„ฑ ์„ค๋ช…์ž).

๋‚ด ๊ฐ€์ •์€ @F ์™€ @F()๊ฐ€ ๋ชจ๋‘ ๋™๋“ฑํ•˜๋ฏ€๋กœ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ 0๊ฐœ ์ด์ƒ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ง€์›ํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋‘ ํ˜ธ์ถœ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์— ํŠนํžˆ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

<strong i="13">@F</strong>  // Performs some default behaviour.
prop: number;

@F({ option: true }) // Performs some configured behaviour.
prop: number;

์ด๊ฒƒ์€ @F ๋Œ€์‹  @F()๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ํ˜ธ์ถœํ•˜์—ฌ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์‹ค์ˆ˜๋ฅผ ํ•˜๊ธฐ ์‰ฝ๊ณ  ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ์ž‘๋™ํ•ด์•ผ ํ•˜๋Š” ๋ชจ์–‘์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์ž‘๋™ํ•˜์ง€ ์•Š์„ ๋•Œ ํ˜ผ๋™ํ•˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.

์ด ๊ฒฝ์šฐ ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

export function F(options?: any): PropertyDecorator {
    return (target, name) => {
        // do something.
    }
}

๊ทธ๊ฒƒ์œผ๋กœ ๋๋‚ฌ์ง€๋งŒ ๋Œ€์‹  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์กฐ์žกํ•œ ์˜ˆ์™€ ๊ฐ™์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

export function F(...args: any[]): any {
   var func = (target, name) => {
      // do something.
   }

   if (args.length === 1) return func;
   else if (args.length === 2) func(args[0], args[1]);
}

์ง„์งœ ๊ณ ํ†ต์ž…๋‹ˆ๋‹ค.

@Tharaxis ์ด ๋™์ž‘์€ @F ๋ฐ @F() ๋Š” ๋™์ผํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. @F ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ F @F ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ @F() ๋Š” ๋นˆ ์ธ์ˆ˜ ๋ชฉ๋ก์œผ๋กœ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์š”์†Œ F ๋ฅผ ํ˜ธ์ถœํ•œ ๋‹ค์Œ ๊ฒฐ๊ณผ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ๋ฌธ์ œ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒฉํ† ๋ฆฌ F ์˜ ์„œ๋ช…์„ ํ• ๋‹น ๊ฐ€๋Šฅํ•œ declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void; ์™€ ๋น„๊ตํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํŒŒ์•…ํ•˜๋ ค๋ฉด ๋” ๊ฐ•๋ ฅํ•œ ํ™•์ธ์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด #3246์„ ๊ธฐ๋กํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹น์‹ ์ด ์˜ฌ๋ฐ”๋ฅธ ์ผ์„ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ๋ฏฟ์œผ๋ฉฐ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒฉํ† ๋ฆฌ์˜ ์ž˜๋ชป๋œ ์‚ฌ์šฉ์„ ํฌ์ฐฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@mhegazy ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์ด ์™œ ๊ทธ๋Ÿฐ์ง€๋Š” ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ @F ๋ฐ @F() ๋™๋“ฑํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ๋ฐฐ์ œํ•˜๋Š” ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ ? ๊ถ๊ทน์ ์œผ๋กœ ๋‘˜ ๋‹ค ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ธฐ๋Šฅ์˜ ๋™์ผํ•œ ํ˜ธ์ถœ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. , ๊ทธ๋“ค ์ค‘ ํ•˜๋‚˜๋งŒ ์™ธ๋ถ€ ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜์— ๋Œ€ํ•œ ํ˜ธ์ถœ์„ ํฌํ•จํ•ฉ๋‹ˆ๊นŒ? ์ด๊ฒƒ์€ ํ™•์‹คํžˆ ๋งค์šฐ ๋†€๋ผ์šด ๋™์ž‘์ด๊ณ  API ์†Œ๋น„์ž์˜ ๊ด€์ ์—์„œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์–ด์•ผ ํ•˜๋Š” ์ด์œ ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์„œ ์ตœ์†Œ ๋†€๋ผ์›€์˜ ์›์น™์ด ์œ„๋ฐ˜๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

JS ๊ด€์ ์—์„œ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์ง€๋งŒ(ํ•˜๋‚˜๋Š” F ํ•จ์ˆ˜์˜ ์ฐธ์กฐ๋ฅผ ์ „๋‹ฌํ•˜๊ณ  ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•œ ๋‹ค์Œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋กœ ํ•ด๋‹น ๊ฒฐ๊ณผ์˜ ์ฐธ์กฐ๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค), ์ €๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. @F ๋กœ ์ „๋‹ฌ๋œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๋นˆ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ชฉ๋ก์ด ์žˆ๋Š” ํŒฉํ† ๋ฆฌ์™€ ์•”์‹œ์ ์œผ๋กœ ์ผ์น˜(๋ฐ ํ˜ธ์ถœ)ํ•  ์ˆ˜ ์—†๋Š” ์ด์œ ๋ฅผ ํ™•์‹คํžˆ ์ดํ•ดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๊ทธ๊ฒƒ์ด ํŒฉํ† ๋ฆฌ์ธ์ง€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์ธ์ง€ ์•Œ ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค. ์ด ์„œ๋ช…์ด ์žˆ๋Š” ๊ฒฝ์šฐ:

declare function decoratorOrFactory (...args: any[]): any;

์ด๊ฒƒ์€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์ž…๋‹ˆ๊นŒ ์•„๋‹ˆ๋ฉด ๊ณต์žฅ์ž…๋‹ˆ๊นŒ? ๋นˆ ์ธ์ˆ˜๋กœ ํ˜ธ์ถœํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ?

์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” ๋Œ€๋ถ€๋ถ„์€ ์„œ๋ช…์„ ํ˜ธ์ถœํ•  ๋•Œ ์„œ๋ช…์ด ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์ผ์น˜ํ•˜์ง€ ์•Š์œผ๋ฉด ์˜ค๋ฅ˜๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@rbuckton ์—๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ๊ณต์žฅ์œผ๋กœ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์— ํ”Œ๋ž˜๊ทธ๋ฅผ ์ง€์ •ํ•ด์•ผ ํ•˜๋Š” #3246์— ๋Œ€ํ•œ ์ˆ˜์ • ์‚ฌํ•ญ์ด ์žˆ์œผ๋ฏ€๋กœ ๊ณ„์† ์ง€์ผœ๋ด ์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

@mhegazy , ๋‚ด๊ฐ€ ๋งํ•˜๋Š” ๊ฒƒ์€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ(์ฆ‰, @F ๋˜๋Š” @F() )๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ _ํ•ญ์ƒ_ ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜ F์˜ ํ˜ธ์ถœ์ด์–ด์•ผ ํ•˜๋ฉฐ, ์ด๋Š” ์ฐจ๋ก€๋กœ ์ ์ ˆํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์œ ํ˜•์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์บก์Šํ™” ํŒฉํ† ๋ฆฌ๊ฐ€ ์—†๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์˜ ์ตœ์ƒ์œ„ ํ‘œํ˜„์€ ์—†์Šต๋‹ˆ๋‹ค.

์ฆ‰, F์˜ ์„œ๋ช…์€ ํ•ญ์ƒ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

declare function F(...args: any[]): ClassDecorator | PropertyDecorator | MethodDecorator | ParameterDecorator;

๋˜๋Š” ๊ทธ์— ์ƒ์‘ํ•˜๋Š” ๊ฒƒ.

๊ทธ๋Ÿฐ ๋‹ค์Œ @F ํ˜ธ์ถœ์€ ์ปดํŒŒ์ผ๋Ÿฌ์—์„œ @F() ์™€ ๋™์ผํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. @F ๋ฐ @F() ์„œ๋ช…์€ ๋ชจ๋‘ ์–ด๋–ค ํ˜•ํƒœ๋กœ๋“  ๊ณต์žฅ ์„œ๋ช…๊ณผ ์ผ์น˜ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ํ˜ธ์ถœ ํ˜ผ๋™ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ํ•œ ๊ฐ€์ง€๋ฟ์ž…๋‹ˆ๋‹ค!

๋‹ค์Œ์„ ๊ฐ์•ˆํ•  ๋•Œ:

declare function F(...args: any[]): PropertyDecorator {
    return (target, name) => {
        // do stuff.
    }
}

@F()
property: number;

๊ทธ๋ฆฌ๊ณ 

declare function F(target, name) { // Matches PropertyDecorator
    // do stuff.
}

<strong i="22">@F</strong>
property: number;

๊ทธ๋“ค์€ ๊ฐ™์€ ์ผ์„ ํ•˜์ง€๋งŒ ๋‚˜๋Š” ๊ทธ๊ฒƒ๋“ค์„ ๋‹ค๋ฅด๊ฒŒ ์„ ์–ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค! ๊ทธ๋Ÿฌ๋‚˜ ์–‘๋ฐฉํ–ฅ์œผ๋กœ ์กด์žฌํ•  ์ˆ˜ ์žˆ๋„๋ก F๋ฅผ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์€ ์ •๋ง ๋ฒˆ๊ฑฐ๋กญ๊ณ  ์ผ๊ด€๋œ ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ๋ฌธ์„œ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ํŒฉํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์„ ํƒํ•˜๊ณ  API ์†Œ๋น„์ž๊ฐ€ ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋ฏธ๋ฆฌ ์ด ๊ตฌ๋ถ„์„ ์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@Tharaxis ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋กœ ์‚ฌ์šฉ๋  F ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ณด๊ณ  ์žˆ๋‹ค๋ฉด @F ์™€ @F() ๊ฐ€ ์™„์ „ํžˆ ๋‹ค๋ฅผ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. C ์™€ C() ๊ฐ€ ๋‹ค๋ฅธ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ฒซ ๋ฒˆ์งธ๋Š” ๊ฐ’์„ ์ฐธ์กฐํ•˜๊ณ  ๋‘ ๋ฒˆ์งธ๋Š” ๊ฐ’์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. @F ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ ์šฉํ•˜๊ณ  @F() ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ๋“ค์€ ๋™์ผํ•œ ์ž‘์—…์ด ์•„๋‹ˆ๋ฉฐ ๊ทธ๋ ‡๊ฒŒ ๋˜์–ด์„œ๋„ ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

@DavidSouther ์ด๊ฒƒ์ด ๊ทธ๋Ÿด ์ˆ˜ ์—†๊ฑฐ๋‚˜ ๊ทธ๋ ‡์ง€ ์•Š์€ ํƒ€๋‹นํ•œ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? @F ํ˜ธ์ถœ๊ณผ @F() ํ˜ธ์ถœ ๊ฐ„์— ๊ธฐ๋Šฅ์  ์ฐจ์ด๋Š” ์—†์ง€๋งŒ ์ •์˜ ๋ฐ ๋ฌธ์„œํ™” ๋ฐฉ๋ฒ• ๊ฐ„์—๋Š” ์ƒ๋‹นํžˆ ํฐ ์ฐจ์ด๊ฐ€ ์žˆ์œผ๋ฉฐ ํ˜ธ์ถœ์— ๋ถˆํ•„์š”ํ•ด์•ผ ํ•˜๋Š” ์ถ”๊ฐ€ ๋ณต์žก์„ฑ์ด ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.

๋‚ด ์ œ์•ˆ์€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ •์˜ํ•˜๋Š” ๋ฐ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์–ด์„œ๋Š” ์•ˆ ๋˜๋ฉฐ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ํ•œ ๊ฐ€์ง€ ์ด์ƒ ์ •์˜ํ•  ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@F ์™€ @F() ํ˜ธ์ถœ ์‚ฌ์ด์—๋Š” ๊ธฐ๋Šฅ์  ์ฐจ์ด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์ด ๋…ผ์Ÿ์˜ ์ฃผ์š” ํฌ์ธํŠธ๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์ด ์‚ฌ์‹ค์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š๋Š”๋‹ค. F๋Š” ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ฐธ์กฐ์ด๊ณ , F()๋Š” ๋นˆ ์ธ์ˆ˜ ์ง‘ํ•ฉ(์˜ˆ: F.call(this, []) )์œผ๋กœ ํ˜ธ์ถœ๋  ๋•Œ F์˜ ๋ฐ˜ํ™˜ ๊ฐ’์— ๋Œ€ํ•œ ์ฐธ์กฐ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ๋“ค์€ ๊ธฐ๋Šฅ์ ์œผ๋กœ, ๊ทธ๋ฆฌ๊ณ  ๊ฐœ๋…์ ์œผ๋กœ ๋‹ค๋ฅธ ๋‘ ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค.

@Tharaxis @F ์™€ @F() ๋Š” ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์˜ ์ฐจ์ด, ๋ฌธ์„œํ™” ๋ฐฉ๋ฒ•์˜ ์ฐจ์ด, ์ ˆ๋Œ€์ ์œผ๋กœ ํ•„์š”ํ•œ ํ˜ธ์ถœ์˜ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์งˆ๋ฌธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์™œ ๋ชจ๋“  ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ธฐ๋Šฅ์ด ํŒฉํ† ๋ฆฌ์—ฌ์•ผ ํ•ฉ๋‹ˆ๊นŒ? ๊ท€ํ•˜์˜ ์ œ์•ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

@mhegazy ํ›„์ž์˜ ์˜ต์…˜( @F() )์€ ๊ฒฉ๋ฆฌ๋œ(๋ฐ ๋ณต์ œ๋œ) ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜์™€ @F ํ˜ธ์ถœ์„ ํ†ตํ•ด ๊ธฐ๋Šฅ์  ํด๋กœ์ €์™€ ์ถ”๊ฐ€ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค๋Š” ์ ์„ ์ธ์ •ํ•ฉ๋‹ˆ๋‹ค. ๋ณธ์งˆ์ ์œผ๋กœ ๊ณต์œ  ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ธฐ๋Šฅ ์ฐธ์กฐ์— ๋Œ€ํ•ด ์ˆ˜ํ–‰ํ•˜๋ฏ€๋กœ ํด๋กœ์ €๋ฅผ ํ†ตํ•œ ๊ฒฉ๋ฆฌ๊ฐ€ "๋” ์•ˆ์ „"ํ•˜๊ณ  ์ผ๊ด€์„ฑ์ด ์žˆ์–ด ๋†€๋ผ์›€์˜ ๊ฐ€๋Šฅ์„ฑ์ด ์ค„์–ด๋“ญ๋‹ˆ๋‹ค.

@DavidSouther ๊ท€ํ•˜์˜ ์งˆ๋ฌธ์€ ๊ท€ํ•˜๊ฐ€ ๊ฐ„๋‹จํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋กœ ์ •์˜ํ•˜๋Š” ๊ฒƒ์— ๋‹ฌ๋ ค ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ์˜ ๊ฐ„๋‹จํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉํ•ดํ•˜๋Š” ๊ฒƒ์€ ์—†์Šต๋‹ˆ๋‹ค.

declare function F(): PropertyDecorator {
    return (target, name) => {
        // do stuff
    }
}

"๊ฐ„๋‹จํ•œ ๊ตฌ๋ฌธ"๋ณด๋‹ค 2์ค„๋งŒ ๋” ๋งŽ๊ณ  ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํ˜ธ์ถœ์ด ๋ฌด์—‡์ธ์ง€ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ์ •์˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์ด ๋งค์šฐ ์ตœ์†Œํ•œ์œผ๋กœ ์นจ์Šต์ ์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ •์˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹จ ํ•˜๋‚˜๋ฟ์ด๋ฏ€๋กœ(์ผ๊ด€์„ฑ์˜ ๊ฐ€์น˜๋ฅผ ๋ฌด์‹œํ•˜์ง€ ๋ง์ž) "๊ฐ„๋‹จํ•œ ๊ตฌ๋ฌธ"๊ณผ ๋น„๊ตํ•˜์—ฌ ์ด๋ฅผ ์™„์„ฑํ•˜๋Š” ๋ฐ ์•ฝ 2์ดˆ๊ฐ€ ๋” ๊ฑธ๋ฆด ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ ๋” ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ๋ฌธ์ œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

declare function F(options?: any): PropertyDecorator {
    return (target, name) => {
        // do stuff
    }
}

@F()
property1: number;

<strong i="15">@F</strong>
property2: number;

@F({ option: true })
property3: number;

์ด ์ค‘ ํ•˜๋‚˜๋Š” ๋‹ค๋ฅธ ๊ฒƒ๊ณผ ๊ฐ™์ง€ ์•Š์Šต๋‹ˆ๋‹ค. @F ์˜ ์‚ฌ์šฉ์€ ์•ก๋ฉด ๊ทธ๋Œ€๋กœ๋Š” ํ™•์‹คํžˆ ์ž‘๋™ํ•˜์ง€๋งŒ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ F์˜ ๊ธฐ๋ณธ ์„ ์–ธ์ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ๋Š”์ง€ ์•Œ์ง€ ๋ชปํ•˜์ง€๋งŒ F๊ฐ€ ์กด์žฌํ•˜๊ณ  ์„ ํƒ์  ์ธ์ˆ˜ ์ง‘ํ•ฉ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ๋งŒ ์•„๋Š” ์‚ฌ๋žŒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•˜์‹ญ์‹œ์˜ค. ๋‚ด๊ฐ€ @F ๋กœ ์‹ค์ˆ˜ํ•  ๊ฐ€๋Šฅ์„ฑ์€ ํ˜„์žฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜์—์„œ ์‚ฌ์†Œํ•œ ์ผ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๊ฐœ๋ฐœ์ž/๋ฌธ์„œ ์ž‘์„ฑ์ž์—๊ฒŒ @F ๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์‚ฌ์‹ค์„ ์†Œ๋น„์ž๊ฐ€ ์ธ์‹ํ•˜๋„๋ก ํ•˜๋Š” ๋ฐ ํฐ ๋ถ€๋‹ด์ด ๋ฉ๋‹ˆ๋‹ค(๊ทธ๋Ÿฌ๋‚˜ @C ๋Š” ์–ด๋–ป๊ฒŒ๋“  "๋‹ค๋ฅด๋ฏ€๋กœ" ์ž‘๋™ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค).

์†Œ๋น„์ž๊ฐ€ ๊ฑฑ์ •ํ•  ํ•„์š”๊ฐ€ ์—†๋Š” "๋ชจ๋“  ์‚ฌ๋žŒ์—๊ฒŒ ๋งž๋Š”" ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์›ํ•œ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋”์ฐํ•œ ์ผ์„ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

declare function F(...args: any[]): any {
    var decorator = (target, name) => {
        // do stuff
    }

    // Heaven forbid your decorator formal parameter list also can take 2 parameters.
    return (args.length === 2) ? decorator(args[0], args[1]) : decorator;
}

์†”์งํžˆ ๋”์ฐํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด์ œ ์ผ๋ฐ˜ํ™”ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ F์— ๋Œ€ํ•œ ๋ชจ๋“  ์ค‘์š”ํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜ ์ธํ…”๋ฆฌ์„ผ์Šค๋ฅผ ์žƒ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ •์˜ํ•˜๊ณ  ๋ฌธ์„œํ™”ํ•˜๊ธฐ ์‰ฝ๊ณ  ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด์„œ๋Š” ํ•  ๋ง์ด ๋งŽ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ์‚ฌ๋žŒ์ด ๊ทธ ์ฝ”๋“œ์˜ ์ž‘์„ฑ์ž์ธ ์šฐ๋ฆฌ์™€ ๊ฐ™์€ ์ง€์‹์ด๋‚˜ ์ดํ•ด๋ ฅ์„ ๊ฐ€์งˆ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋„๋ก ์Šค์Šค๋กœ๋ฅผ ์†์ด์ง€ ๋ง™์‹œ๋‹ค.

@Tharaxis ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์œ„ํ•œ ๋””์ž์ธ ์ดˆ๊ธฐ์— ์ด๊ฒƒ์— ๋Œ€ํ•ด ์ƒ๊ฐํ–ˆ๊ณ  ๊ตฌ์ฒด์ ์ธ ์š”์ ์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. @mhegazy ์™€ @DavidSouther ๊ฐ€ ์ด ์Šค๋ ˆ๋“œ์—์„œ ์ด์ „์— ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ์ด ๋™์ž‘์€ JavaScript ํ•จ์ˆ˜์˜ ํ‘œ์ค€ ๋™์ž‘๊ณผ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค.

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์™€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒฉํ† ๋ฆฌ ๋ชจ๋‘์˜ ์—ญํ• ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๋ ค๋Š” ์‹œ๋„๋Š” ๋‹ค์†Œ ๋ณต์žกํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด ๋งž์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ผ๋ฐ˜์ ์œผ๋กœ ํ•ญ์ƒ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒฉํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์ด ๊ด€ํ–‰์ด ์ฑ„ํƒ๋˜๋„๋ก ๋ฆฐํ„ฐ์— ๊ทœ์น™์„ ์ œ๊ณตํ•˜๋Š” ๋ชจ๋ฒ” ์‚ฌ๋ก€๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚˜์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์— ๋Œ€ํ•œ ์œ ํ˜• ๊ฒ€์‚ฌ์˜ ๋ถˆ์ผ์น˜์— ๋Œ€ํ•œ ์ด์ „ ์š”์ ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋ฐฉ๊ธˆ PR #3249๋ฅผ ์ œ์ถœํ–ˆ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” @rbuckton ๋‹˜ ,

์ €๋Š” @Tharaxis๊ฐ€ ์–ธ๊ธ‰ํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ž˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์‚ฌ์šฉ์ž ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค...

๋‚ด๊ฐ€ ๊ฐ€์งˆ ์งˆ๋ฌธ์€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ๊ธฐ๋Šฅ๊ณผ ์ผ์น˜ํ•ด์•ผ ํ•˜๋Š”๊ฐ€? ์ฆ‰, ํ•จ์ˆ˜์˜ ๊ฒฝ์šฐ this.f ๋Œ€ this.f()๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์€ ๋‚ด๊ฐ€ ๊ฐ’์„ ์›ํ•  ๋•Œ๋„ ์žˆ๊ณ  ๊ฐ’์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์„ ์›ํ•  ๋•Œ๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์™„์ „ํžˆ ์˜๋ฏธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์˜ ๊ฒฝ์šฐ ์–ธ์–ด ๊ธฐ๋Šฅ ์ˆ˜์ค€์—์„œ ๋‚˜์—๊ฒŒ ๋ช…ํ™•ํ•˜์ง€ ์•Š์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‹จ์ง€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ @F ๋ฅผ ์ ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ์ฃผ์žฅํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ํŒฉํ† ๋ฆฌ ๋˜๋Š” ์ •์  ๋ฉ”์†Œ๋“œ๋กœ ๊ตฌํ˜„๋˜์—ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์ •๋ง๋กœ ์•Œ๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ์ผ๋ถ€ ๊ธฐ๋Šฅ์„ ์žƒ์–ด๋ฒ„๋ฆฌ์ง€ ์•Š๋Š” ํ•œ ๋ง์ž…๋‹ˆ๋‹ค.

์œ„์˜ ๋‚ด์šฉ์ด ์ž˜๋ชป๋˜์—ˆ๊ฑฐ๋‚˜ ๋ฌด์ง€ํ•œ ๊ฒฝ์šฐ ์‚ฌ๊ณผ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ์ €๋Š” ๋น„๊ต์  ์ƒˆ๋กœ์šด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์„ธ๊ณ„์ž…๋‹ˆ๋‹ค.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค & ๊ฑด๋ฐฐ

๋˜ํ•œ ๊ทธ ์งˆ๋ฌธ์„ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. "ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ •์˜๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์—"๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ์‹ค์ œ ์ด์œ ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์—๋งŒ _if_ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ๋ฌธ์  ๋™๋“ฑ์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ์˜๋ฏธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ •์˜ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด _๋ฐœ์ƒ_ํ•˜๋Š” ๊ธฐ๋Šฅ๊ณผ ์™„์ „ํžˆ ๊ด€๋ จ์ด ์—†๋Š” ๊ธฐ๋Šฅ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ @F ๋ฐ @F() ๊ฐ€ ๋™์ผํ•˜์ง€ ์•Š๋‹ค๋Š” ์‚ฌ์‹ค์€ ๋‹ค์Œ ๋ฌธ์ œ๋ฅผ ์œ ๋ฐœํ•ฉ๋‹ˆ๋‹ค.

  • @F ์™€ @F() ์˜ ์ฐจ์ด์ ๊ณผ ์ด๊ฒƒ์ด ์ž‘๋™ํ•˜๋Š” ์ด์œ ์™€ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ์ด์œ ( @F ๋Œ€ @F() ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์ด์œ )๋ฅผ ์ดํ•ดํ•ด์•ผ ํ•˜๋Š” ๊ฐœ๋ฐœ์ž declare function A(params?: any): ParameterDecorator ๋Œ€ declare function B(target, name) , @A ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์ง€๋งŒ @A() ๋Š” ์ž‘๋™ํ•˜๊ณ  @B ๋Š” ์ž‘๋™ํ•˜์ง€๋งŒ @B() ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์ง€๋งŒ ์ธ์ง€์ ์œผ๋กœ๋Š” ์ธ์ˆ˜๊ฐ€ ์—†๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์˜ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.
  • ์ฝ”๋“œ ์ˆ˜์ค€์—์„œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์˜ ํ˜ธ์ถœ ๊ตฌ๋ฌธ์„ ์ ์ ˆํ•˜๊ฒŒ ๋ฌธ์„œํ™”ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ฑฐํ•˜๋Š” ์–ด์ˆ˜์„ ํ•œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฆฌํŒฉํ† ๋ง์€ '์›์‹œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ'( @F )๋ฅผ ์ƒ์„ฑํ–ˆ๊ณ  ์ด์ œ ์ผ๋ถ€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ(๊ทธ๋Ÿฌ๋‚˜ ์ด์ „ ๋ฒ„์ „๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•ด ์„ ํƒ์‚ฌํ•ญ์œผ๋กœ ์„ค์ •) ์•ฝ๊ฐ„ ๋” ๋งŽ์€ ์ž‘์—…์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ ๋ฐฉ๋ฒ•์—์„œ๋Š” ๋ชจ๋“  @F ์ ์šฉ์„ @F() ๋กœ ๋ฆฌํŒฉํ† ๋งํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ถ€๋Š” ์ฝ”๋“œ ๋‚ด์—์„œ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๋กœ ๋ณ€๊ฒฝํ•˜์‹ญ์‹œ์˜ค.

@Tharaxis @F ์™€ @F() ์ด ์†Œ๋น„์ž์—๊ฒŒ ๋†’์€ ์ธ์ง€ ๋ถ€๋‹ด์ด ๋  ์ˆ˜ ์žˆ์Œ์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‘ ์ฝ”๋“œ๊ฐ€ ๋™๋“ฑํ•˜๊ฒŒ ๋™์ž‘ํ•˜๋„๋ก ๋‚ด๋ณด๋‚ธ ์ฝ”๋“œ์™€ ๋™์ž‘์„ ๋ณ€๊ฒฝํ•˜๋„๋ก ์š”์ฒญํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋“ค๋ฆฝ๋‹ˆ๋‹ค. ์ด๋Š” ๋‘ ๊ฐ€์ง€ ํ˜•์‹์ด ๋™์ผํ•˜๊ฒŒ ์ทจ๊ธ‰๋  ๊ฐ€๋Šฅ์„ฑ์ด ๋งค์šฐ ๋‚ฎ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์œ„ํ•œ ES7 ์ œ์•ˆ๊ณผ ์ถฉ๋Œํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ฐœ์‚ฐ์œผ๋กœ ์ด์–ด์ง„๋‹ค๋ฉด ์ข‹์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋˜ ๋‹ค๋ฅธ ์š”์ ์€ ์—ฌ๊ธฐ์„œ ํ˜ผ๋™์ด ํ•จ์ˆ˜๋ฅผ ์ฝœ๋ฐฑ์œผ๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ๊ณผ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ ์‚ฌ์ด์˜ ํ˜ผ๋™๊ณผ ์œ ์‚ฌํ•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹น์‹ ์ด ์ด๊ฒƒ์„ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ๋‹ค๋ฉด

function callbackFactory() {
     return function(...args: any[]) { // do stuff };
}
function takesCallback(cb: (...args: any[]) => void) { }
takesCallback(callbackFactory());

์‚ฌ์šฉ์ž๋Š” ํ˜ผ๋ž€ ์ „ํ™”๋ฅผ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค takesCallback(callbackFactory) ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  callbackFactory . ์ด๊ฒƒ์€ ์‹ค์ œ๋กœ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์— ๋Œ€ํ•ด ์ง€์ ํ•œ ํ˜ผ๋™๊ณผ ๊ฐ™์ง€๋งŒ ์–ธ์–ด๊ฐ€ ์ด ๋‘ ํ˜•์‹์„ ๋™์ผํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ์ •๊ทœํ™”ํ•˜๋ฉด ํ‘œํ˜„๋ ฅ์ด ์†์‹ค๋ฉ๋‹ˆ๋‹ค. ๋•Œ๋กœ๋Š” ๊ตฌ๋ถ„์ด ์ค‘์š”ํ•˜๋ฉฐ ์œ ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์—๊ฒŒ๋„ ์ ์šฉ๋˜๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ ์ด๋ก ์ƒ์œผ๋กœ๋Š” ํ™•์‹คํžˆ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

@JsonFreeman ๋‚˜๋Š” ๋‹น์‹ ์˜ ์ฃผ์žฅ์„ ์ •๋ง๋กœ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์œ„ํ•œ ES7 ์ œ์•ˆ์ด ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ž์‹ ์˜ ์‹ค์ฒด๋กœ ์ดํ•ดํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๋ง์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๊ฒŒ ์ „๋ถ€์ž…๋‹ˆ๋‹ค. ES7 ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ๊ทธ์ € ํ•˜๋‚˜์˜ _์ œ์•ˆ_์ด๊ณ  ์ œ๊ฐ€ ์•„๋Š” ํ•œ, ๊ทธ๋“ค์€' ๋ถ€๋ถ„์ ์œผ๋กœ Google๊ณผ ๊ท€ํ•˜ ์ž์‹ ์ด ์„ค๋ช…ํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ž‘์—…์˜ ์กฐํ•ฉ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋งž์Šต๋‹ˆ๊นŒ? ์ž‘๋™ ๋ฐฉ์‹์— ๋Œ€ํ•ด์„œ๋Š” ์•„์ง ๊ฒฐ์ •๋œ ๋ฐ”๊ฐ€ ์—†์œผ๋ฉฐ ์ œ์•ˆ์„œ๊ฐ€ ์Šน์ธ ์ „์— _๋งŽ์€_ ๋ฐ˜๋ณต์„ ๊ฑฐ์น˜๊ฒŒ ๋  ๊ฒƒ์ด๋ฏ€๋กœ TS์—์„œ ์ผ๊ด€๋œ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•˜๋„๋ก ํ•œ ๋‹ค์Œ (์ ์–ด๋„ ์‹œ๋„) TS์—์„œ ์–ป์€ ๊ฒฝํ—˜์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์•„์ด๋””์–ด ๋’ค์— ์ œ์•ˆ์— ๊ด€๋ จ๋œ ๋‹ค์–‘ํ•œ ๋‹น์‚ฌ์ž? ES6 ์‚ฌ์–‘์ด ์•ฝ๊ฐ„ ๋‹ค๋ฅธ ๋™์ž‘์„ ์š”๊ตฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— TS๊ฐ€ ๋‚˜์ค‘์— ๋ฆฌํŒฉํ† ๋งํ•ด์•ผ ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•œ ๊ฒƒ์€ ์ด๋ฒˆ์ด ์ฒ˜์Œ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์•„์ง ์กด์žฌํ•˜์ง€ ์•Š๊ณ  ์•„์ง ํ•ฉ์˜๋˜์ง€ ์•Š์€ ์‚ฌ์–‘์— ๋Œ€ํ•ด ์ถ”์ ํ•˜๋Š” ํ•œ _ํ•ญ์ƒ_ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

ํ•จ์ˆ˜์— ๊ด€ํ•œ ๋‹น์‹ ์˜ ์˜ˆ์— ๊ด€ํ•ด์„œ๋Š”, ์šฐ๋ฆฌ๊ฐ€ ํ•จ์ˆ˜๊ฐ€ ์‹ค์ œ๋กœ๋Š” ์™„์ „ํžˆ ๋‹ค๋ฅธ ๊ตฌ์กฐ์ผ ๋•Œ(๊ทธ๋ฆฌ๊ณ  ๊ทธ๋ž˜์•ผ๋งŒ ํ•  ๋•Œ) ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์™€ ๋ณ‘ํ•ฉํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. JavaScript์—์„œ ํ•จ์ˆ˜๋กœ ์ž‘์—…ํ•  ๋•Œ ํ•จ์ˆ˜๊ฐ€ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ๋˜๋Š”์ง€ ์ดํ•ดํ•˜๊ณ  ํ•จ์ˆ˜ ์ฐธ์กฐ์™€ ํ•จ์ˆ˜ ํ˜ธ์ถœ์˜ ์ฐจ์ด์ ์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋กœ์„œ ์–ด๋–ค ์šฉ๋„๋กœ ์‚ฌ์šฉ๋˜๋Š”์ง€์— ๋Œ€ํ•ด์„œ๋Š” ํ˜ผ๋™์ด ์—†์Šต๋‹ˆ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ํ•จ์ˆ˜๊ฐ€ _์•„๋‹™๋‹ˆ๋‹ค_ ํ•จ์ˆ˜์˜ ๋™์ž‘์„ ์ƒ์†ํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ํด๋ž˜์Šค๊ฐ€ ํ•จ์ˆ˜๋ผ๊ณ  ๋งํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ ํ•จ์ˆ˜๋Š” ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋” ๋ถ„๋ช…ํ•œ ๋ฐฉ๋ฒ•์ด ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ES6 ์ด์ „์— ํด๋ž˜์Šค๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๋ฐฉ์‹์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ํด๋ž˜์Šค๋Š” ํ•จ์ˆ˜์˜ ์†์„ฑ์„ ์ทจํ•˜์ง€ ์•Š์œผ๋ฉฐ ํ•จ์ˆ˜์ฒ˜๋Ÿผ ํด๋ž˜์Šค๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†์ง€๋งŒ ES6 ์ด์ „์˜ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ž˜์Šค๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , ๋‚˜๋Š” ๊ทธ ๋ฌธ์ œ์— ๋Œ€ํ•œ ๋‚˜์˜ ๋…ผ์ ์„ ๋‹ค ์จ๋ฒ„๋ ธ๋‹ค๊ณ  ๋Š๋‚€๋‹ค. ๋‚˜๋Š” ๋‹จ์ง€ ์„ ํƒ์„ ํ•ด๊ฒฐํ•ด์•ผ ํ•  ๊ฒƒ์ด๋‹ค. ๋‚ด ์ฝ”๋“œ์—์„œ๋Š” ์ผ๊ด€์„ฑ์„ ์œ„ํ•ด ํ•ญ์ƒ ํŒฉํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์—ฌ์ „ํžˆ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๋ฌธ์ž ๊ทธ๋Œ€๋กœ ํ•จ์ˆ˜๋กœ ์ทจ๊ธ‰ํ•˜๋Š” ๊ฒƒ์ด ๋ฏธ๋ž˜์— ๋งŽ์€ ์ขŒ์ ˆ์„ ์ผ์œผํ‚ฌ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ, ๊ทธ๊ฒƒ์€ ๋‹จ์ง€ ๋‚˜์ž…๋‹ˆ๋‹ค.

@mhegazy ์ด๊ฒƒ์€ ๋‚ด๊ฐ€ @jonathandturner ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ https://github.com/jonathandturner/decorators/issues/16 ์ €๋Š” ์ด๊ฒƒ์ด ์ƒ๊ฐํ•ด์•ผ ํ•  ๋ฌธ์ œ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ๋กœ์„œ๋Š” ์ด ๋””์ž์ธ ์„ ํƒ์ด "ES7 Decorator Pitfalls"์™€ ์œ ์‚ฌํ•œ ์ œ๋ชฉ์˜ ๋งŽ์€ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์˜ ์ฃผ์ œ๊ฐ€ ๋  ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค.

@Tharaxis , ์ฒซ ๋ฒˆ์งธ ์š”์ ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ES7 ์ œ์•ˆ์ด ์šฐ๋ฆฌ๊ฐ€ ๋ฌด์–ธ๊ฐ€๋ฅผ ์ž˜ ๋””์ž์ธํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉํ•ดํ•ด์„œ๋Š” ์•ˆ ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์šฐ๋ฆฌ ๋””์ž์ธ์€ ์–ด์จŒ๋“  ES7์˜ ์„ ๊ตฌ์ž ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.

"๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ํ•จ์ˆ˜ ์ธ์ˆ˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค"์— ๋Œ€ํ•ด ๋‚ด๊ฐ€ ํ‹€๋ฆฌ์ง€ ์•Š์•˜๋‹ค๋ฉด ์šฐ๋ฆฌ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ž์ฒด์— ๋Œ€ํ•ด ๋…ผ์˜ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒฉํ† ๋ฆฌ์— ๋Œ€ํ•ด ๋…ผ์˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์™€ ํ•จ์ˆ˜์˜ ๊ตฌ๋ถ„์— ๊ด€๊ณ„์—†์ด ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ _factories_๋Š” ์‹ค์ œ๋กœ๋Š” ํ•จ์ˆ˜์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ผ๋ฐ˜ ํ•จ์ˆ˜์ธ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒฉํ† ๋ฆฌ์— ๋Œ€ํ•œ ํ˜ธ์ถœ์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๋„๋ก ์š”์ฒญํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋“ค๋ฆฝ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ์ผ์ด ๋ฐœ์ƒํ•˜๋ฉด ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒฉํ† ๋ฆฌ์™€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๊ตฌ๋ถ„ํ•  ๋ฐฉ๋ฒ•์ด ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ํ•จ์ˆ˜๋กœ ์ทจ๊ธ‰ํ•  ๋•Œ ์ข‹์€ ์ ์€ ์†Œ๋น„์ž๊ฐ€ ๊ทธ๊ฒƒ์„ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋กœ ์ ์šฉํ•˜๊ฑฐ๋‚˜ ๋‹จ์ˆœํžˆ ์ ์ ˆํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ๋Œ€๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@JsonFreeman ์ธ์ˆ˜๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์„ค๋ช…ํ•˜๊ณ  ํ˜ธ์ถœํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋Š” ํ˜„์žฌ ์ƒํ™ฉ์„ ์ค‘์‹ฌ์œผ๋กœ ๋Œ์•„

๋‚ด๊ฐ€ ๋ฌป๋Š” ๊ฒƒ์€ ์˜ˆ์ž…๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ @F ๋ฅผ @F() ํ˜ธ์ถœ์— ํ•ด๋‹นํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ๋„๋ก ํ•˜๊ณ  ์œ ํ˜• ๊ฒ€์‚ฌ๊ฐ€ ์‚ฌ์šฉํ•  ๋•Œ 0...n ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์ธ์ˆ˜ ๋ชฉ๋ก์„ ์š”๊ตฌํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ ๋Œ€๊ด„ํ˜ธ ์—†๋Š” ๊ตฌ๋ฌธ. ์•„๋งˆ๋„ ๋‹น์‹ ์€ "...ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒฉํ† ๋ฆฌ์™€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๊ตฌ๋ณ„ํ•  ๋ฐฉ๋ฒ•์ด ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค..."๊ฐ€ ์˜๋ฏธํ•˜๋Š” ๋ฐ”๋ฅผ ์ž์„ธํžˆ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ํ•ญ์ƒ ๊ณต์žฅ์—์„œ ๋‹ต์žฅ์„ ํ•˜๊ณ , ๊ณต์žฅ๋ช…์€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ด๋ฆ„์ธ๋ฐ... ๋ณ„๋กœ ์–ด๋ ต์ง€ ์•Š์€๋ฐ ์ œ๊ฐ€ ์ž˜๋ชป ์ดํ•ดํ•˜๊ณ  ์žˆ๋Š” ๊ฑด๊ฐ€์š”?

์†Œ๋น„์ž๊ฐ€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ ์šฉํ•˜๋„๋ก ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ๋งˆ์ง€๋ง‰ ์š”์ ์€ ๋ชจ๋“  ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ํŒฉํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ์ž˜ ์„ค๋ช…๋˜์–ด ์žˆ์œผ๋ฉด ์ง์ ‘ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. <decorator name>(target, name) ์™€ ๋น„๊ตํ•˜์—ฌ <decorator name>(<argument list>)(target, name) ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. <decorator name>(target, name) ๋ฅผ ์˜ˆ๋กœ ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŒฉํ† ๋ฆฌ ์‚ฌ์šฉ์„ ์˜๋ฌดํ™”ํ•œ๋‹ค๋Š” ๊ฒƒ์€ ์ „์ž์˜ ์˜ˆ๊ฐ€ ํ•ญ์ƒ ์ž‘๋™ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜์ง€๋งŒ ๊ฐ•์ œํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ํ›„์ž์˜ ์˜ˆ๋Š” ๋•Œ๋•Œ๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์œผ๋ฉฐ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ๊ตฌํ˜„๋˜๋Š” ๋ฐฉ์‹์— ์ „์ ์œผ๋กœ ์˜์กดํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์— ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๋Š” ์ ์„ ์ง€์ ํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚ด ๋ฌธ์ œ๋Š” ๋™์ผํ•œ ๊ฒƒ์„ ์„ค๋ช…ํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์ผ๊ด€์„ฑ ๋ฌธ์ œ๋กœ ์ด์–ด์ง„๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํŠนํžˆ ๊ทธ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ํ˜ธ์ถœ ๋ฐฉ๋ฒ•์ด ๋‹ฌ๋ผ์•ผ ํ•จ์„ ์˜๋ฏธํ•  ๋•Œ ํŠนํžˆ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ฆฌํŒฉํ† ๋ง์—์„œ ์–ธ์–ด ์ผ๊ด€์„ฑ์— ์ด๋ฅด๊ธฐ๊นŒ์ง€ ๋ชจ๋“  ๊ฒƒ์„ ๋ฐฉํ•ดํ•˜๋Š” ๋ถˆ์ผ์น˜์ž…๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๋ช‡ ๊ฐ€์ง€ ํฌ์ŠคํŠธ์—์„œ ์„ค๋ช…ํ•œ ๋ฆฌํŒฉํ† ๋ง ๋ฌธ์ œ๋Š” ์ด๋ฏธ ํ˜„์žฌ ๋ฐฉ๋ฒ•์„ ๊ฒ€์‚ฌํ•ด์•ผ ํ•˜๋Š” ์ด์œ ์— ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”, @Tharaxis ๊ฐ€ ๋งํ•œ ๋‚ด์šฉ์— ๋”ฐ๋ผ ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž์—๊ฒŒ 1.5์„ผํŠธ โ€‹โ€‹๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ ํ˜„์žฌ ์ œ์•ˆ์— ๋งŒ์กฑํ•ฉ๋‹ˆ๋‹ค.
a) ์šฐ์ฃผ๊ฐ€ ๊ทธ๊ฒƒ์„ ๋ช…๋ นํ•ฉ๋‹ˆ๋‹ค.
b) ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ์ƒํ™ฉ์ด ๋‹ค๋ฅธ ๊ฒฝ์šฐ ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ์„ ์žƒ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

ํ›„์ž๋Š” ๋ฌผ๋ก  ๊ฐ€์น˜ ํŒ๋‹จ์ด๋ฉฐ ๋‹ต์€ ๊ฐœ๋ฐœ์ž ์œ ํ˜•(์˜ˆ: ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž/์ „๋ฌธ ์‚ฌ์šฉ์ž ๋“ฑ)์— ๋”ฐ๋ผ ์–ด๋Š ์ •๋„ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. ์ €๋Š” ์ „์ž ๋ฒ”์ฃผ์— ์†ํ•˜๋ฉฐ ์ผ๋ฐ˜์ ์œผ๋กœ ์—ฌ๋Ÿฌ ์–ธ์–ด์™€ ํ”„๋ ˆ์ž„์›Œํฌ์— ๊ฑธ์ณ ์–‡๊ฒŒ ํผ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‚˜์—๊ฒŒ '์ค‘์š”ํ•œ ๊ธฐ๋Šฅ'์—๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ 2๊ฐ€์ง€ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐ์„ฑ์ด ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์ ˆ์ถฉ์•ˆ์˜ ์˜ˆ๋Š” ์กด์žฌํ•œ๋‹ค๋ฉด ํ›Œ๋ฅญํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด์ƒ์ ์œผ๋กœ๋Š” @F ๋ฐ @F()๊ฐ€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ๊ตฌํ˜„๋˜๋Š” ๋ฐฉ์‹์— ๊ด€๊ณ„์—†์ด ์ผ๊ด€๋  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ข‹๊ฒ ์ง€๋งŒ ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด ํ’€๋ฐญ์—์„œ ๊ฐˆํ€ด๋ฅผ ํ”ผํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ํŒฉํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ์ œ์•ฝ์„ ๋ฐ›๋Š” ๊ฒƒ์„ ํ›จ์”ฌ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๊ทธ๋“ค์„ ์‚ฌ์šฉํ•  ๋•Œ๋งˆ๋‹ค.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค & ๊ฑด๋ฐฐ

์ด ์š”์ฒญ์€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒฉํ† ๋ฆฌ๊ฐ€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ‘œ์ค€์ ์ธ ๋ฐฉ๋ฒ•์ด๋ผ๋Š” ์•„์ด๋””์–ด์— ๋‹ฌ๋ ค ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์ด๊ฒƒ์ด ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ์ž๊ฐ€ ์›์‹œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ •์˜ํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์žฅ์‹ ์ •์˜ํ•˜๋ฉด F , ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ @F ๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค @F() ๋Œ€์‹  F ์ž์ฒด์˜ ๋‹ค์Œ F๋ฅผ ํ˜ธ์ถœ์˜ ๊ฒฐ๊ณผ๊ฐ€ ์žฅ์‹์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒฉํ† ๋ฆฌ ๋Œ€์‹  ์›์‹œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ ์šฉํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์–ด๋”˜๊ฐ€์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๋œป์ธ๊ฐ€์š”?

์ด ์•„์ด๋””์–ด๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์™€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒฉํ† ๋ฆฌ์˜ ์ž์—ฐ์Šค๋Ÿฌ์šด ๊ตฌ์„ฑ์„ ๋’ค์ง‘๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋Š๊ปด์ง‘๋‹ˆ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์œ„์— ๊ตฌ์ถ•๋œ ์ถ”์ƒํ™” ๋ ˆ์ด์–ด์ธ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒฉํ† ๋ฆฌ์™€ ํ•จ๊ป˜ ์—ฌ๊ธฐ์—์„œ ํ™•์‹คํžˆ ๊ธฐ๋ณธ ๊ตฌ์กฐ์ฒ˜๋Ÿผ ๋Š๊ปด์ง‘๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ๋“ค์€ ๋‹จ์ง€ ํ•˜๋‚˜์˜ ํŒจํ„ด์ผ ๋ฟ ๊ทธ ์ด์ƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋Œ€์‹  ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒฉํ† ๋ฆฌ๊ฐ€ ํ‘œ์ค€์ ์ธ ๊ฒƒ, ๊ธฐ๋ณธ์ด ๋œ๋‹ค๋ฉด ์‚ฌ๋žŒ๋“ค์€ ์ธ์ˆ˜๋ฅผ ์ทจํ•˜์ง€ ์•Š๊ณ  ํ‰ํ‰ํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋งŽ์€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํŒฉํ† ๋ฆฌ๋ฅผ ์ •์˜ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋งค์šฐ ์–ด๋ฆฌ์„๊ฒŒ ๋Š๊ปด์ง€๊ธฐ ์‹œ์ž‘ํ•˜๊ณ  ๋ฌด์—‡์ด ๊ธฐ๋ณธ์œผ๋กœ ๊ฐ„์ฃผ๋˜๊ณ  ๋ฌด์—‡์ด ๋” ๋ณต์žกํ•œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋˜๋Š”์ง€์— ๋Œ€ํ•œ ์ž์—ฐ์Šค๋Ÿฌ์šด ์ง๊ด€์„ ๋’ค์ง‘์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์— ๋Œ€ํ•ด ๋งค์šฐ ์กฐ์‹ฌํ•˜๋Š” ํ•œ ๊ฐ€์ง€๋Š” ๊ณผ๋„ํ•œ ๋งˆ๋ฒ•์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ฐœ์ธ์ ์œผ๋กœ ์ฝ”๋“œ๊ฐ€ ๋ฌด์—‡์„ ํ•˜๋Š”์ง€ ์ดํ•ดํ•˜์ง€ ๋ชปํ•  ๋•Œ ๊ธด์žฅํ•˜๊ณ , ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ž‘์„ฑํ•˜์ง€ ์•Š์€ ์ถ”๊ฐ€ ํ˜ธ์ถœ์„ ๋น„๋ฐ€๋ฆฌ์— ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ ๋„ˆ๋ฌด ๋งŽ์€ ๋ถ€๋‘๊ต์ฒ˜๋Ÿผ ๋Š๊ปด์ง‘๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” @JsonFreeman ,

๋‚ด๊ฐ€ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ๋‚ด ์ทจํ–ฅ์€ ํ•ญ์ƒ ์ถ”์•…ํ•จ์„ ์‚ฌ์šฉ์ž๊ฐ€ ์•„๋‹Œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์˜ ์ž‘์„ฑ์ž์™€ ํ•จ๊ป˜ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋งŽ์€ ์ธ์ˆ˜๊ฐ€ ์—†๋Š” ํŒฉํ† ๋ฆฌ๊ฐ€ ๋งค์šฐ ์ถ”์•…ํ•˜๋‹ค๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์˜ˆ

// wraps rawDecoratorMethod in a no-arg factory method.
<strong i="8">@Decorator</strong>
function rawDecoroatorMethod(target, name, descriptor) {...}
// looks like this one would be a no-op... so that feels not quite right unless there's other advantages.
<strong i="11">@DecoratorFactory</strong>
function decoroatorFactoryMethod(someArg) {...}

์–ด์จŒ๋“ , ๊ทธ๋Ÿฌํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์ด ์˜๋ฏธ๊ฐ€ ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ํŒ๋ช…๋  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ฃผ์„์ด ํ•จ์ˆ˜์˜ ๋ชฉ์ ์„ ๋ฌธ์„œํ™”ํ•œ๋‹ค๋Š” ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰ ์žฅ์‹ํ•ฉ๋‹ˆ๋‹ค.

๊ฑด๋ฐฐ

์ข‹์€ ์œก์ฆ™, ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ •์˜ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ, Typeception์˜ ์‹ฌ๊ฐํ•œ ๊ฒฝ์šฐ.

@JsonFreeman ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ 0์ธ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋Œ€์‹  ๋‹ค์ˆ˜์˜ (๋Œ€์ƒ, ์ด๋ฆ„) ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋ฐ˜๋“œ์‹œ ์ถ”์•…ํ•œ ๊ฒƒ์ธ์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ตœ์†Œํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ 0์ธ ํ•จ์ˆ˜๊ฐ€ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ์— ์—†๋Š” ํŠน์ •์„ฑ/๋ช…ํ™•์„ฑ ์ˆ˜์ค€์„ ์ œ๊ณตํ•˜๊ณ (ํ›„์ž์˜ ๊ฒฝ์šฐ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ํ˜ธ์ถœ๊ณผ ์ผ์น˜ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—) ๊ทธ ์œ„์— ๋ฌธ์„œํ™”ํ•  ๋‹จ์ผ ๋Œ€์ƒ์„ ์ œ๊ณตํ•˜๋Š” ๊ฒฝ์šฐ ๋ถˆํ•„์š”ํ•œ ์ˆ˜์ค€์˜ ๋ถˆ์ผ์น˜. ๋‚˜๋Š” ๋˜ํ•œ ์ธ์ง€๋œ "๊ฐ€๋Šฅํ•œ" ๋ณต์žก์„ฑ์œผ๋กœ ์ธํ•ด ํ•œ ๊ฒฝ๋กœ๋กœ ๊ฐ€๋Š” ๊ฒƒ์„ ๊บผ๋ คํ•˜์ง€๋งŒ, ํ˜„์žฌ ๊ตฌํ˜„์ด ์†Œ๋น„ ์ธก๋ฉด์— ๋ถ€๊ณผํ•˜๋Š” ๋งค์šฐ ์‹ค์ œ์ ์ธ "๋ช…๋ฐฑํ•œ" ๋ณต์žก์„ฑ์— ๋น„์ถ”์–ด ๋ณผ ๋•Œ ๋” ๋งŽ์€ ์‹ค์ˆ˜๋ฅผ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•œ ๊ฒƒ๋ณด๋‹ค ๋ถ„๋ช…ํ•œ ๊ฒƒ.

๋‹ค๋ฅธ ์˜ต์…˜์€ @F ๋กœ ํ˜ธ์ถœ๋˜๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ClassDecorator, MethodDecorator, PropertyDecorator ๋˜๋Š” ParameterDecorator์˜ ํŒจํ„ด ๋˜๋Š” ClassDecorator, MethodDecorator, PropertyDecorator๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” 0..n ์ธ์ˆ˜ ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜ ์ค‘ ํ•˜๋‚˜์™€ ์ผ์น˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜๋Š” ParameterDecorator. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ ๊ตฌํ˜„์ด ๋‹ค๋ฅธ ์˜ค๋ฅ˜๋ฅผ ์ผ์œผํ‚ค๊ณ (์ถฉ๋Œํ•˜๋Š” ๋‘ ํ•จ์ˆ˜๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์–ด๋–ค ๊ฒƒ์ด ๊ฐ€์žฅ ์ž˜ ์ผ์น˜ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๊นŒ?) ์ปดํŒŒ์ผ๋Ÿฌ ๋‚ด์—์„œ ๊ณผ๋„ํ•œ ๋ณต์žก์„ฑ์„ ์ถ”๊ฐ€ํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‹จ์ˆœํžˆ @F ํ˜ธ์ถœ์„ @F() ๊ฒƒ์ด ๋” ๊ฐ„๋‹จํ•œ ์†”๋ฃจ์…˜์ด ๋  ๊ฒƒ์ด๋ฉฐ ๋ช…์‹œ๋œ ๋‹ค์–‘ํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ๋ช…ํ™•ํžˆํ•˜๊ธฐ ์œ„ํ•ด ๊ท€ํ•˜์˜ ์†”๋ฃจ์…˜์ด ๋ณต์žกํ•˜๋‹ค๊ณ  ์ฃผ์žฅํ•œ ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ ์šฉํ•˜๊ธฐ ์ „์— ์ž๋™์œผ๋กœ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ๋ถˆํˆฌ๋ช…ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ–ˆ์Šต๋‹ˆ๋‹ค. ์‚ฝ์ž…๋œ ํ˜ธ์ถœ์€ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์ด์ง€ ์•Š์œผ๋ฉฐ ๋งŽ์€ ์‚ฌ์šฉ์ž๊ฐ€ ๊ธฐ๋Œ€ํ•˜์ง€ ์•Š์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ์˜ ๋ชจ์Šต๋„ ๋ณต์žกํ•˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ง€์ ํ–ˆ๋“ฏ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž‘์„ฑ์ž๋Š” ์ž์‹ ์˜ ๊ธฐ๋Šฅ์ด ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋กœ ์ ์šฉ๋˜์–ด์•ผ ํ•˜๋Š”์ง€ ์—ฌ๋ถ€์— ๋Œ€ํ•ด ๋ชจํ˜ธํ•˜๊ฑฐ๋‚˜ ๋ง‰์—ฐํ•œ ์ƒ๊ฐ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๋‹น์‹ ์—๊ฒŒ ์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ข‹์€ ๋„์„œ๊ด€์€ ๊ทธ๊ฒƒ์„ ๋ถ„๋ช…ํžˆ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ œ์•ˆํ•œ ์ฒด๊ณ„์—์„œ ์ž๋™์œผ๋กœ ํ˜ธ์ถœ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ ์‹๋ณ„์ž ๋Œ€์‹  ์ž„์˜์˜ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ฉ๋‹ˆ๊นŒ? ๊ทธ๊ฒƒ๋„ ํ˜ธ์ถœ๋˜๋‚˜์š”?

๋‹ฌ๋ฆฌ ๋ฌธ์„œํ™”๋˜์ง€ ์•Š๋Š” ํ•œ ์•”์‹œ์  ํ˜ธ์ถœ์€ ๋†€๋ผ์šธ ์ˆ˜ ์žˆ์ง€๋งŒ C# ํŠน์„ฑ ๋“ฑ๊ณผ ๊ฐ™์€ ๊ฐœ๋…์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋งŒ ํ•ด๋‹น๋œ๋‹ค๋Š” ์ ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

์ž„์˜์˜ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํ‘œํ˜„์ด ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๋Š”์ง€ ์ž์„ธํžˆ ์„ค๋ช…ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

์ข‹์€ ์œก์ฆ™, ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ •์˜ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ, Typeception์˜ ์‹ฌ๊ฐํ•œ ๊ฒฝ์šฐ.

๊ณต์ •ํ•œ ์ „ํ™”. ์ฃผ๋ง ์˜คํ›„ ๋Šฆ์€ ์‹œ๊ฐ„์— ์ œ๋Œ€๋กœ ์ƒ๊ฐํ•˜์ง€ ๋ชปํ•œ ์˜๊ฒฌ์„ ์ œ์‹œํ•˜๋Š” ๋ฐ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ๊ตํ›ˆ์„ ์–ป์—ˆ๋‹ค. ์ธํ„ฐ๋„ท.์‹คํ–‰ ์ทจ์†Œ().

๋‚ด ์š”์ ์€ ์ผ๊ด€๋œ ํ˜ธ์ถœ ์‚ฌ์ดํŠธ ๊ตฌ๋ฌธ์ด ํŒฉํ† ๋ฆฌ ์‚ฌ์šฉ์„ ์˜๋ฌดํ™”ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ํŒ๋ช…๋˜๋ฉด ๊ทธ ์ด์ƒ์œผ๋กœ ๋งŒ์กฑํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ์˜์‹ฌ ํ•  ์—ฌ์ง€์—†์ด ๋ณด์ผ๋Ÿฌ ํ”Œ๋ ˆ์ดํŠธ๋ฅผ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ž‘์„ฑํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค์‹œ ํ•œ ๋ฒˆ ๋‚˜๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋ฐ˜๋ณต๋˜๋Š” ๊ณ ํ†ต๋ณด๋‹ค ์•ฝ๊ฐ„์˜ ๊ณ ํ†ต์„ ์„ ํ˜ธํ•ฉ๋‹ˆ๋‹ค(์ด ์‹œ์ ์—์„œ ์ž ์žฌ์ ์ธ ๊ณ ํ†ต์ด์ง€๋งŒ). ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์€ ๋™์˜ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

API ํ–ฅ์ƒ์—๋„ ๋ฌธ์ œ๊ฐ€ ์žˆ์ง€ ์•Š์Šต๋‹ˆ๊นŒ? ํŒฉํ† ๋ฆฌ ์—†์ด ์ƒ์„ฑ๋œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ๋‚˜์ค‘์— ์„ ํƒ์  ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ๋ฏธ๋ž˜์— @F ๋ฐ @F2() ๋ฅผ ์˜ˆ์ธกํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋˜ํ•œ f ๋ฐ f() ์‚ฌ์šฉํ•  ๋•Œ ์ด ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์–ป์„ ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ์ด๋“ค์€ ์†Œ๋น„ ์ธก๋ฉด์—์„œ ์„œ๋กœ ๋‹ค๋ฅธ ์‚ฌ์šฉ ์‚ฌ๋ก€์ž…๋‹ˆ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์˜ ๊ฒฝ์šฐ์—๋Š” ํ•ญ์ƒ ๋Œ€์ƒ์— ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ ์šฉ/ํ˜ธ์ถœํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ํ•ญ์ƒ ๋ฐฐํ›„์—์„œ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์ด ์ง„ํ–‰๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋‚˜์—๊ฒŒ ์ด๊ฒƒ์˜ ํ•ต์‹ฌ์€ ์‚ฌ์šฉ์„ฑ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ ์šฉํ•  ๋•Œ ์ž‘์„ฑ์ž๊ฐ€ ๊ตฌํ˜„ํ•œ ๋ฐฉ๋ฒ•์„ ์ฐพ๊ธฐ ์œ„ํ•ด Google์„ ๊ฒ€์ƒ‰ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ํŒจํ‚ค์ง•์ด ์•„๋‹ˆ๋ผ ๋™์ž‘์— ๊ด€์‹ฌ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฑด๋ฐฐ

์š”์•ฝํ•  ๋งˆ์ง€๋ง‰ ๋ฉ”๋ชจ๋งŒ ๋‚จ๊ธฐ๊ณ  ์กฐ์šฉํžˆ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์š”์ปจ๋Œ€, ์ด๊ฒƒ์€ ์ •๋ง๋กœ ์ €์—๊ฒŒ ์žˆ์–ด ์ธํ„ฐ๋ž™์…˜ ๋””์ž์ธ ๋ฌธ์ œ์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ์™ธ๋ถ€์—์„œ ๋””์ž์ธ๋œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๋ณด๊ณ  ์‹ถ์ง€๋งŒ ๊ทธ ๋ฐ˜๋Œ€๋Š” ์•„๋‹™๋‹ˆ๋‹ค.

UI/UX ์ „๋ฌธ๊ฐ€๋กœ์„œ ์ €๋Š” ์ด๊ฒƒ์„ ๊ฝค ์ž์ฃผ ๋ด…๋‹ˆ๋‹ค. ์ €๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ํ”ผํ•ด๋ฅผ ์ค„ ์ˆ˜ ์žˆ๋Š” UI ์†”๋ฃจ์…˜์„ ์ œ์•ˆํ•œ ์žฌ๋Šฅ ์žˆ๋Š” ๊ฐœ๋ฐœ์ž์™€ ํ•จ๊ป˜ ์ผํ–ˆ์Šต๋‹ˆ๋‹ค(ํ•œ ๊ฐ€์ง€ ์˜ˆ๋Š” ํŠธ๋žœ์žญ์…˜ ๋ณต์žก์„ฑ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ํ•œ ๊ฒฝ์šฐ์— ๋‘ ๊ฐœ์˜ ์ €์žฅ ๋ฒ„ํŠผ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์‹œ ๋˜‘๋˜‘ํ•œ ์‚ฌ๋žŒ๊ณผ ์ข‹์€ ์‚ฌ๋žŒ). ๋ณต์žกํ•œ ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ ๋…ผ๋ฆฌ์— ๋Œ€ํ•ด ๋ฌด๋ฆŽ์„ ๊ฟ‡๊ณ  ์žˆ์„ ๋•Œ ์•Œ๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ์žŠ๊ณ  ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž์˜ ๋ˆˆ์œผ๋กœ ๋ณด๋Š” ๊ฒƒ์ด ์–ด๋ ค์šธ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ ๋‚ด๊ฐ€ ํ‰๊ท ์ ์œผ๋กœ ์™„์ „ํžˆ ํ‹€๋ ธ๊ฑฐ๋‚˜ ๋ณต์žก์„ฑ์ด ํ˜„์žฌ ๋””์ž์ธ์„ ์š”๊ตฌํ•œ๋‹ค๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ์ข‹๋‹ค๋ฉด, ๋‚˜๋Š” ๊ทธ์ € ์ •์‹ ์„ ์ฐจ๋ฆฌ๊ณ  ๋ฐฐ์›Œ์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฑด๋ฐฐ

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ์‹๋ณ„์ž๊ฐ€ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ํ‘œํ˜„์‹์ธ ๊ฒฝ์šฐ ์ž๋™์œผ๋กœ ํ˜ธ์ถœํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ์˜ˆ๋ฅผ ๋“ค์–ด ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ผ๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋Œ€์ฒด ํ•จ์ˆ˜ ํ‘œํ˜„์‹์œผ๋กœ OR ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ:

@(F || function (target) { // default decorator behavior })
class C { }

๊ทธ๋Ÿฌ๋ฉด ์ด๊ฒƒ์„ ์ž๋™์œผ๋กœ ํ˜ธ์ถœํ•ฉ๋‹ˆ๊นŒ? ์ ์šฉ๋˜๊ธฐ ์ „์— ๊ธฐ๋ณธ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋ฏ€๋กœ ์ž˜๋ชป๋œ ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(F || function (target) { // default decorator behavior })()

์ด๊ฒƒ์€ ์˜ณ์ง€ ์•Š์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@JsonFreeman , ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ตฌ๋ฌธ์€ ์ด์™€ ๊ฐ™์€ ์ž„์˜์˜ ํ‘œํ˜„์‹์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๊นŒ? ๋‚˜๋Š” ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ์Šค์Šค๋กœ ๋งค๋‹ฌ๋ฆด ๋งŒํผ ๋งŽ์€ ๋ฐง์ค„์„ ์‚ฌ์šฉํ•˜๋„๋ก ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋ฐ˜๋“œ์‹œ ์ข‹์€ ์ƒ๊ฐ์ด๋ผ๊ณ  100% ํ™•์‹ ํ•˜์ง€ ๋ชปํ•˜์ง€๋งŒ, ๊ทธ๊ฒƒ์€ ๋‹จ์ง€ ๋‚˜์ž…๋‹ˆ๋‹ค(์ˆœ์ „ํžˆ ๋‚˜๋Š” ์žฌ์‚ฌ์šฉ/๋ณด์ผ๋Ÿฌ ํ”Œ๋ ˆ์ดํŠธ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ์ž„์˜์˜ ํ‘œํ˜„์„ ๋ณด์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋Œ€์‹  ์ฝ”๋“œ๋ฅผ ๋ณด๊ธฐ ํ‰ํ•˜๊ฒŒ ๋งŒ๋“ค๊ณ  ๋”ฐ๋ผํ•˜๊ธฐ๊ฐ€ ํ›จ์”ฌ ๋” ์–ด๋ ต๊ฒŒ ๋งŒ๋“œ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

์ฆ‰, ์ž„์˜์˜ ํ‘œํ˜„์‹ ์ž์ฒด๊ฐ€ ๋™์ผํ•œ ํŒฉํ† ๋ฆฌ ๊ตฌ๋ฌธ์œผ๋กœ ํ‰๊ฐ€๋˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ์ž‘๋™ํ•  ๊ฒƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@(F || () => function(target) { /* default decorator behaviour */ })
class C { }

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๋‹น์‹ ์˜ ์ž„์˜์˜ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ฃผ์œ„์— ์•ฝ๊ฐ„ ๋” ์„ฑ๊ฐ€์‹  ๋น„ํŠธ๋ฅผ ๋„ฃ์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์— ๋™์˜ํ•˜์ง€๋งŒ ์ž„์˜์˜ ํ‘œํ˜„์‹์„ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ () => ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ํฐ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ : ๋ถ„๋ช…ํžˆ ๋žŒ๋‹ค ๊ตฌ๋ฌธ์ด ์„ ์–ธํ•˜๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์ด๋ผ๋Š” ์˜๋ฏธ๋Š” ์•„๋‹ˆ์ง€๋งŒ () => ๊ฐ€ function() { return function(target) { /*...*/ } } ๋ณด๋‹ค ์•ฝ๊ฐ„ ๋” ์ข‹์Šต๋‹ˆ๋‹ค.

์ด ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํ˜ธ์ถœ ๊ตฌ๋ฌธ ํ† ๋ก ์„ ๋ฐฉํ•ดํ•ด์„œ ์ •๋ง ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ํ‘œํ˜„์‹์ด ํ˜ธ์ถœ๋˜๋Š” ์ˆœ์„œ๋ฅผ ๊ณต์‹์ ์œผ๋กœ ๋ช…ํ™•ํžˆ ํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ํŠนํžˆ, ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๋Œ€์ƒ ์œ ํ˜•์˜ ๋ผ์ธ์„ ๋”ฐ๋ผ ์›๋ž˜ ์†Œ์Šค์—์„œ ๋Œ€์ƒ ๋ฉค๋ฒ„์˜ ์œ„์น˜์™€ ๋‹จ์ผ ๋Œ€์ƒ์—์„œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์˜ ์ˆœ์„œ์ž…๋‹ˆ๋‹ค.

@billccn ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ์•„๋ž˜์—์„œ ์œ„๋กœ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์›๋ณธ ์†Œ์Šค ์ฝ”๋“œ์—์„œ

class C {
    <strong i="7">@F</strong>
    <strong i="8">@G</strong>
    method() { }
}

์ด๊ฒƒ์€ ๋จผ์ € ๋ฉ”์„œ๋“œ์— G๋ฅผ ์ ์šฉํ•œ ๋‹ค์Œ ๊ฒฐ๊ณผ์— F๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋‹น์‹ ์ด ๋ฌป๋Š” ๊ฒƒ์ž…๋‹ˆ๊นŒ?

์ด๊ฒƒ์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ:

<strong i="6">@A</strong>
class Clazz {
    <strong i="7">@B</strong>
    prop = 1;

    <strong i="8">@C</strong>
    method() {}

    <strong i="9">@D</strong>
    get prop() {return 1;}

    <strong i="10">@E</strong>
    method2() {}

    <strong i="11">@F</strong>
    prop2 = 1;
}

๋ฒ”์œ„ ์ˆœ์„œ๋ฅผ ๋”ฐ๋ฅด๋ฏ€๋กœ ๋ชจ๋“  ์†์„ฑ/๋ฉ”์„œ๋“œ๋ฅผ ๋จผ์ € ์„ ์–ธํ•œ ๋‹ค์Œ ํด๋ž˜์Šค 1์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ์ฆ‰, B, C, D, E, F, A.

์—ฌ๊ธฐ ์—์„œ ์ƒ์„ฑ๋œ ์ฝ”๋“œ๋ฅผ ๋ณผ ์ˆ˜

ํ˜„์žฌ ๋งค๊ฐœ๋ณ€์ˆ˜ ์†์„ฑ์„ ์žฅ์‹ํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ง€์›๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๋งค๊ฐœ๋ณ€์ˆ˜ ์†์„ฑ์€ constructor(private prop: Type) ์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์†์„ฑ(ํ•„๋“œ)๊ณผ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ํ•จ๊ป˜ ์„ ์–ธ๋ฉ๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ๋‘˜ ๋‹ค ์žฅ์‹๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ƒ์ƒ๋ ฅ์ด ํ’๋ถ€ํ•œ ๊ตฌ๋ฌธ์„ ๋ฐœ๋ช…ํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์งˆ๋ฌธ: ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ผ๋ฐ˜ ๊ฐœ์ฒด ๋ฉ”์„œ๋“œ์˜ ๋™์ž‘์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

var isCreatorUser = () => {  /* code that verifies if user is the creator */ },
    isAdminUser = () => { /* code that verifies if user is admin */ },

var routeConfig = {
    get() {},
    <strong i="7">@isCreatorUser</strong> patch() {},
    <strong i="8">@isAdminUser</strong> <strong i="9">@isCreatorUser</strong> delete() {}
};

... ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด ์™œ? ์ •๋ง ์œ ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•„์ง์€ ์•„๋‹ˆ์ง€๋งŒ ๊ณ ๋ คํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. @rbuckton์— ์ž์„ธํ•œ ๋‚ด์šฉ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ๋ฐ์ฝ”๋ ˆ์ดํŒ…๋˜๋Š” ์œ ํ˜•์—์„œ ๋ฐ์ฝ”๋ ˆ์ดํŠธ๋œ ๊ฒฐ๊ณผ ์œ ํ˜•์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋Š” ์ด์œ ๋ฅผ ์—ฌ์ญค๋ด๋„ ๋ ๊นŒ์š”?

์˜ˆ๋ฅผ ๋“ค์–ด MethodDecorator๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋Œ€์•ˆ์ ์œผ๋กœ ์ œ์•ˆ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

declare type MethodDecorator = <T, R>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<R> | void;

๋”ฐ๋ผ์„œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ์‚ฌ์šฉํ•˜๊ธฐ์— ๋” ์œ ์—ฐํ•˜๊ณ  ๋งคํฌ๋กœ์ฒ˜๋Ÿผ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํŠธ๋œ ํด๋ž˜์Šค/ํ•„๋“œ์˜ ์œ ํ˜•์€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๋ฐ˜ํ™˜ ์œ ํ˜•์— ๋”ฐ๋ผ ์—…๋ฐ์ดํŠธ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์œ ํ˜• ์•ˆ์ „์„ฑ์ด ๊ณ„์† ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

https://github.com/jonathandturner/brainstorming/blob/master/README.md#c4 -defining-a-decorator๊ฐ€ ๋ฐ˜ํ™˜ ์œ ํ˜•์ด ๋™์ผํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๋ช…์‹œํ–ˆ์Œ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ type validity ๋Š” ์—ฌ๊ธฐ์—์„œ ์œ ํšจํ•œ ์ฃผ์žฅ์ด ์•„๋‹™๋‹ˆ๋‹ค. IMHO. ์ฒซ์งธ, JavaScript์˜ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ํด๋ž˜์Šค/ํ•„๋“œ ์œ ํ˜•์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ TS์™€ JS ๊ฐ„์— ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋‘˜์งธ, ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ์ •์ ์œผ๋กœ ์ ์šฉ๋˜๋ฉฐ, TS ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ •์˜ ์‚ฌ์ดํŠธ์—์„œ ์›๋ž˜ ํ•„๋“œ ์œ ํ˜•๊ณผ ๋ฐ์ฝ”๋ ˆ์ดํŠธ๋œ ํ•„๋“œ ์œ ํ˜•์„ ์ถ”๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@HerringtonDarkholme ๋‚˜๋Š” ์ด๊ฒƒ์„ ๋‹ค๋ฅธ ์ œ์•ˆ์—์„œ ์ถ”์ ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๋งํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ฃผ๋œ ์ด์œ ๋Š” ์œ ํ˜•์— ๋Œ€ํ•œ ์ปดํŒŒ์ผ๋Ÿฌ์˜ ์ด์œ ๊ฐ€ ์„ ์–ธ์„ ํ†ตํ•œ ๋ฐฉ์‹์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์œ ํ˜•์ด ์„ ์–ธ๋˜๋ฉด ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ฏน์Šค์— ์œ ํ˜• ๋ฎคํ…Œ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค๋Š” ๊ฒƒ์€ ํ„ธ์ด ๋งŽ์•„์งˆ ์ˆ˜ ์žˆ๋Š” ์„ ์–ธ์„ ํ•ด๊ฒฐํ•  ๋•Œ ์ด๋ฅผ ํ•ด๊ฒฐํ•ด์•ผ ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

@mhegazy ๊ทธ๋ž˜์„œ, ์ด๊ฒƒ์„ ์˜๋„์ ์ธ ์„ค๊ณ„๊ฐ€ ์•„๋‹ˆ๋ผ ๊ตฌํ˜„ ์šฉ์ด์„ฑ์„ ์œ„ํ•œ ํƒ€ํ˜‘์œผ๋กœ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์ด ์ œ์•ˆ ์— ๋”ฐ๋ฅด๋ฉด ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ์„ ์–ธ์  ๊ตฌ๋ฌธ์„ ์œ ์ง€ํ•˜๋ฉด์„œ ๋””์ž์ธ ํƒ€์ž„์— ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ๋ณต์›ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค์Œ ์ฝ”๋“œ๋Š”
๋ฏธ๋ž˜์˜ JavaScript์—์„œ๋Š” ์œ ํšจํ•˜์ง€๋งŒ ์˜ค๋Š˜๋‚ ์˜ TypeScript์—์„œ๋Š” ์œ ํšจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

function SafeCtor(target) {
  var safe = function(...args) {
    var instance = Object.create(target.prototype)
    target.call(instance, ...args)
    return instance
  }
  safe.prototype = target.prototype
  return safe
}

<strong i="10">@SafeCtor</strong>
class Snake {
  constructor(name) {
    this.name = name
  } 
}

var snake = Snake('python')
alert(snake instanceof Snake)

์ด ๊ธฐ๋Šฅ์„ ์ง€์›ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์ ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๊ฒƒ์€ structural ๋Œ€ nominal ํƒ€์ดํ•‘๊ณผ ๊ฐ™์€ ์œ ์‚ฌํ•œ ์ด์•ผ๊ธฐ๊ฐ€ ์•„๋‹˜์„ ํ™•์ธํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ํ™•์ธ์€ ๋Œ€์ƒ์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์—์„œ ๋ฌด์–ธ๊ฐ€๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ˆ„๋ฝ๋œ ๋ถ€๋ถ„์€ ์œ ํ˜•์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์‚ฌํ•ญ์„ ์บก์ฒ˜ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ๊ทธ๊ฒƒ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์•„์ด๋””์–ด๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์ง€๋งŒ, ์šฐ๋ฆฌ๋„ ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์‹ค์ œ๋กœ ์ƒ๊ฐํ•œ ์ ์ด ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์ •๋‹นํ•œ ์ œ์•ˆ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ๊ทธ๊ฒƒ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ๋“œ๋Š” ๋น„์šฉ์ด ๋งค์šฐ ๋†’์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด์ƒ์ ์œผ๋กœ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ์œ ํ˜•์ด ๋Œ€์ƒ๊ณผ ๋™์ผํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ํ• ๋‹น์˜ ์†Œ์Šค ๋˜๋Š” ๋Œ€์ƒ ์œ„์น˜์—์„œ ๋ฐ์ฝ”๋ ˆ์ดํŒ…๋œ ์œ ํ˜•์„ ์‚ฌ์šฉํ• ์ง€ ์—ฌ๋ถ€๋Š” ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ •๋ง๋กœ ์šฐ๋ฆฌ๊ฐ€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๋ฐ˜ํ™˜ ์œ ํ˜•๊ณผ ํƒ€๊ฒŸ์„ ๋ณ‘ํ•ฉํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ์ผ์ข…์˜ ๋ฏน์Šค์ธ(mixin)๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ ์•„์ด๋””์–ด์ž…๋‹ˆ๋‹ค. TypeScript ์ปดํŒŒ์ผ๋Ÿฌ ์ถœ๋ ฅ์ด JavaScript์ด๊ธฐ ๋•Œ๋ฌธ์— Xtend ์™€ ๊ฐ™์€ Java์šฉ ์œ ์‚ฌํ•œ ์–ธ์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ํฅ๋ฏธ๋กœ์šด ์•„์ด๋””์–ด์— ๋Œ€ํ•ด ๋ฐฐ์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ™œ์„ฑ ์ฃผ์„์„ ์ฐพ์Šต๋‹ˆ๋‹ค. "ํ™œ์„ฑ ์ฃผ์„์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ด Xtend ์†Œ์Šค ์ฝ”๋“œ๋ฅผ Java ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜ ํ”„๋กœ์„ธ์Šค์— ์ฐธ์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค."

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ํ†ตํ•ด TypeScript ์ถœ๋ ฅ์„ ์ œ์–ดํ•˜๋Š” โ€‹โ€‹๊ฒƒ์€ ์ •๋ง ์ข‹์€ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค!

์ธํ„ฐํŽ˜์ด์Šค์šฉ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ๊ฐ€๋Šฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@shumy ๋ฌธ์ œ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋Ÿฐํƒ€์ž„์— ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉฐ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ๋Ÿฐํƒ€์ž„์—๋งŒ ์‹คํ–‰๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜ ๊ฐ’๊ณผ ๊ด€๋ จํ•˜์—ฌ ์†์„ฑ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๋ฉ”์„œ๋“œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์™€ ๋‹ค๋ฅด๊ฒŒ ์ทจ๊ธ‰ํ•˜๋Š” ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? (๋ฐ”๋ฒจ์€ ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค).

๋‚ด ๋ง์€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ํ†ตํ•ด ์†์„ฑ์— ๋Œ€ํ•œ ๊ธฐ๋Šฅ์„ ์ •์˜ํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

function decorator(proto, name) {
    Object.defineProperty(proto, name, { value: 42 });
}

class Foo {
    <strong i="7">@decorator</strong>
    a: number;
}

Babel์€ ์„ค๋ช…์ž๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•˜๋Š” ๋ฐ˜๋ฉด:

function decorator(proto, name) {
    return { value: 42 };
}

class Foo {
    <strong i="11">@decorator</strong>
    a;
}

์ด๊ฒƒ์€ Babel์—์„œ ์‚ฌ์šฉ๋  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ผ๋ถ€์ธ TypeScript์—์„œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์†์„ฑ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๋ฉ”์„œ๋“œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์™€ ๋™์ผํ•˜๊ฒŒ ์ทจ๊ธ‰ํ•˜๊ณ  ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์˜ ๋ฐ˜ํ™˜ ๊ฐ’์„ Object.defineProperty ๋ฅผ ํ†ตํ•ด ์ ์šฉํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋˜ํ•œ ๋ฉ”์„œ๋“œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋‹จ์ผ ์†์„ฑ์— ์—ฌ๋Ÿฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ (Babel ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•œ) ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ์†์„ฑ์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ ์™ธ์—๋„ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์—์„œ ์„ค๋ช…์ž๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ด์ง€๋งŒ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋‚ญ๋น„๋˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

function decorator(proto, name) {
    var d = { value: 42 };
    Object.defineProperty(proto, name, d);
    return d;
}

@mhegazy ์œ„์˜ ๋‚ด ์˜๊ฒฌ์— ๋Œ€ํ•œ ํ†ต์ฐฐ๋ ฅ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@sccolbert TypeScript ์—์„œ ๋ฐ์ดํ„ฐ ์†์„ฑ์˜ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์— ๋Œ€ํ•œ ์†์„ฑ ์„ค๋ช…์ž์˜ ์‚ฌ์šฉ์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๊ธฐ๋กœ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์„ค๋ช…์ž๊ฐ€ ์ง€์ •ํ•œ "๊ฐ’"์ด ์ธ์Šคํ„ด์Šค๊ฐ€ ์•„๋‹Œ ํ”„๋กœํ† ํƒ€์ž…์— ์„ค์ •๋œ๋‹ค๋Š” ์‚ฌ์‹ค ๋•Œ๋ฌธ์— ๋Ÿฐํƒ€์ž„์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. . ์œ„์˜ ์˜ˆ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š์ง€๋งŒ ๋‹ค์Œ์„ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค.

function decorator(proto, name) {
  return { value: new Point(0, 0); }
}

class Foo {
  <strong i="7">@decorator</strong>
  p: Point;

  setX(x) { this.p.x = 1; }
}

let a = new Foo();
let b = new Foo();
console.log(a.p.x); // 0
b.setX(10);
console.log(a.p.x); // 10 (!)

์ƒ์„ฑ์ž ๋™์•ˆ ํ‰๊ฐ€๋  ์„ค๋ช…์ž์˜ "์ดˆ๊ธฐํ™”" ์†์„ฑ์„ ์ง€์›ํ•˜๋Š” ES์˜ ๋ฏธ๋ž˜ ๋ฒ„์ „์— ๋Œ€ํ•œ ์ œ์•ˆ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๊ฐ’์ด ํ”„๋กœํ† ํƒ€์ž…์— ์„ค์ •๋˜๋Š”์ง€ ๋˜๋Š” ์ธ์Šคํ„ด์Šค๋ณ„๋กœ ํ• ๋‹น๋˜๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ง€๊ธˆ์€ ์ฃผ์„์˜ ์˜ˆ์— ๋”ฐ๋ผ Object.defineProperty ์ง์ ‘ ํ˜ธ์ถœํ•˜์—ฌ ์ด ์ œํ•œ์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ž์œผ๋กœ ์ด ์ œํ•œ์„ ์™„ํ™”ํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ๊ณ„์† ์กฐ์‚ฌํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@rbuckton ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๊ฐ™์€ ์˜๋ฏธ๋กœ ์ˆ˜๋ ดํ•˜๊ธฐ ์œ„ํ•ด Babel๊ณผ ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๊ฒŒ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ ๊ฐ™์•„์š”.

ํŠน์ • ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ๊ฐ’์„ ์ง€์ •ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์™œ ์œ ์šฉํ•œ๊ฐ€์š”? ์†์„ฑ ์ด๋‹ˆ์…œ๋ผ์ด์ €๊ฐ€ ๊ทธ๋Ÿฐ ์šฉ๋„๊ฐ€ ์•„๋‹Œ๊ฐ€์š”?

๋‚ด ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” ์˜ˆ์ œ๋ณด๋‹ค ๋” ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์†์„ฑ์˜ this ์ปจํ…์ŠคํŠธ์— ๋ฐ”์ธ๋”ฉ๋œ ๊ฐœ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” getter๋ฅผ ์ •์˜ํ•˜์—ฌ ํ•ด๋‹น ๊ฐœ์ฒด์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์ •์˜๋œ ์ธ์Šคํ„ด์Šค์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

๋‹น์‹ ์€ ๋ชจ๋ฐฉ๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ์„ค๋ช… ํ”„๋กœํ† ์ฝœ์„ ๋ฐฉ๋ฒ•์—๊ฒŒ ์ ‘๊ทผ ํŒŒ์ด์ฌ์—์„œ bar ํด๋ž˜์Šค์— ์ •์˜ ๋œ Foo ์ธ์Šคํ„ด์Šค๋ฅผ ํ†ตํ•ด foo (์ฆ‰, foo.bar )์ด๋ฅผ ํ˜ธ์ถœ __get__ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์˜ ๋ฐฉ๋ฒ• BoundMethod . ํ•ด๋‹น ๊ฐœ์ฒด๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด ๊ธฐ๋ณธ ํ•จ์ˆ˜๊ฐ€ self ๋ฅผ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์‚ฌ์šฉํ•˜์—ฌ ํ˜ธ์ถœ๋˜๋ฉฐ ์ด ๊ฒฝ์šฐ foo ์ž…๋‹ˆ๋‹ค. ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ฃผ๋ณ€์— ํ†ต๊ณผํ•ด์•ผ ์ด์œ ๋Š”์ด ๊ฐœ๋…์ด์—†๋Š” thisArg ํ•˜๊ณ  ์ „ํ™” function.bind ์—ฌ๊ธฐ ์ €๊ธฐ๋ฅผ.

์ œ ๊ฒฝ์šฐ์—๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํ˜•์‹์ด ์•ˆ์ „ํ•œ ์‹ ํ˜ธ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
https://github.com/phosphorjs/phosphor-signaling/blob/1.0.1/src/index.ts#L144

์†์„ฑ์— ์•ก์„ธ์Šคํ•˜๋ฉด ์†Œ์œ ์ž์˜ this ์ปจํ…์ŠคํŠธ์— ๋ฐ”์ธ๋”ฉ๋œ ISignal ๊ตฌํ˜„์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์‹ ํ˜ธ๊ฐ€ ์ •์˜๋œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋‹ค์‹œ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
https://github.com/phosphorjs/phosphor-signaling/blob/1.0.1/src/index.ts#L263

๋”ฐ๋ผ์„œ ์‚ฌ์‹ค์ƒ ์ด ์žฅํ™ฉํ•œ ๋™๋“ฑํ•œ ํ•ญ๋ชฉ์˜ ์ง€๋ฆ„๊ธธ๋กœ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

class Foo {
  valueChanged: ISignal<number>;
}

defineSignal(Foo.prototype, 'valueChanged');

@rbuckton

ES3๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•  ๋•Œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์™œ์š”? ES3์—์„œ __decorate ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๋ง‰๋Š” ์–ด๋–ค ๊ฒƒ๋„ ๋ณผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

ES3์—์„œ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ์†์„ฑ ์„ค๋ช…์ž๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
9์›” 4์ผ 2015๋…„ 2:03 PM, "Koloto" [email protected] a รฉcrit :

@rbuckton https://github.com/rbuckton

ES3๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•  ๋•Œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์™œ์š”? ES3์—์„œ __decorate๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉํ•ดํ•˜๋Š” ์–ด๋–ค ๊ฒƒ๋„ ๋ณผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

โ€”
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ฑฐ๋‚˜ GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/Microsoft/TypeScript/issues/2249#issuecomment -137717517
.

@sccolbert ์†์„ฑ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ณด๋‹ค ES6 ํ”„๋ก์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋”

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

@DavidSouther ๋ธŒ๋ผ์šฐ์ €๋Š” ์•„์ง ํ”„๋ก์‹œ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค :(

@cybrown ์˜ˆ, ๋ฉ”์„œ๋“œ ๋ฐ ์ ‘๊ทผ์ž์— ๋Œ€ํ•œ ์†์„ฑ ์„ค๋ช…์ž๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜ ์†์„ฑ(์ ‘๊ทผ์ž๊ฐ€ ์—†๋Š” ํ•„๋“œ)์—์„œ๋งŒ ํ…Œ์ŠคํŠธํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์†์„ฑ(์ ‘๊ทผ์ž ์—†์Œ) ๋ฐ ํด๋ž˜์Šค์— ๋Œ€ํ•ด ES3์—์„œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ํ—ˆ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ES3๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•  ๋•Œ ๋ฉ”์†Œ๋“œ์— ๊ฐ€์งœ ์†์„ฑ ์„ค๋ช…์ž๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. { writable: true, enumerable: true, configurable: true } ์™€ ๊ฐ™์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ES3๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์„ ์ด์œ ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

@sccolbert ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค . ๊ทธ๊ฒƒ์€ ์˜๋ฏธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ง๋ถ™์—ฌ์„œ, TypeScript๋Š” ๊ธฐ๋Šฅ๊ณผ ๋ฉ”์†Œ๋“œ์— ๋Œ€ํ•œ ๊ฐœ์„ ๋œ _this_ ํƒ€์ดํ•‘ ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ๋„์›€์ด ๋˜์ง€ ์•Š์„๊นŒ ์‹ถ์Šต๋‹ˆ๋‹ค. ํƒ€์ดํ•‘์ด ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€๋งŒ ๋Ÿฐํƒ€์ž„ ์˜๋ฏธ๋ก ์ž…๋‹ˆ๋‹ค.

@JsonFreeman ๊ฐœ์„ ๋œ _this_ ํƒ€์ดํ•‘์€ ๋‹ค๋ฅธ ์‚ฌ์šฉ ์‚ฌ๋ก€์—์„œ ํฅ๋ฏธ๋กญ๊ฒŒ ๋“ค๋ฆฝ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ๋” ๋งŽ์€ ์ •๋ณด๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

_this_ ํƒ€์ดํ•‘์— ๋Œ€ํ•œ ๊ฐ€์žฅ ๋ฐœ์ „๋œ ํ† ๋ก ์€ #3694์— ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ฑด๋ฐฐ!

์˜ค๋ฅ˜ TS1207: ๊ฐ™์€ ์ด๋ฆ„์˜ ์—ฌ๋Ÿฌ get/set ์ ‘๊ทผ์ž์— ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

<strong i="6">@get</strong>
public get myValue():any{...}

<strong i="7">@set</strong>
public set myValue(value:any){...}

์œ„์˜ ์ฝ”๋“œ๋Š”

<strong i="11">@get</strong>
<strong i="12">@set</strong>
public get myValue():any{...}

public set myValue(value:any){...}

Getter ๋ฐ setter๋Š” Obect.defineProperty์— ๋Œ€ํ•œ ํ•œ ๋ฒˆ์˜ ํ˜ธ์ถœ๋กœ ์ •์˜๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์˜คํžˆ๋ ค js์˜ ๋‹จ์ , set๊ณผ get์˜ ์„ ์–ธ์€ ๋ณ„๊ฐœ์ด์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ๋™์ผํ•œ ์†์„ฑ ์„ ์–ธ์ž…๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ์˜ ์˜ค๋ฅ˜ ๊ฒ€์‚ฌ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋ณ„๋„๋กœ ์ƒ๊ฐํ•  ๋•Œ ๊ฒฝ๊ณ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ์†์„ฑ ์„ค๋ช…์ž์— ํ•œ ๋ฒˆ๋งŒ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋™์ผํ•œ ์ด๋ฆ„์˜ get ๋ฐ set์„ ๊ฐ์ง€ํ•˜๊ณ  ๋‹จ์ผ Object.defineProperty๋กœ ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋„ ๊ฒฐํ•ฉํ•˜์ง€ ์•Š๋Š” ์ด์œ ๊ฐ€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.
๋˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ ์ด๋“ค์„ ๊ฒฐํ•ฉํ•˜๊ณ  ์˜ค๋ฅ˜๋ฅผ ๋˜์ง€๋Š” ๋Œ€์‹  ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๋ฅผ ๋‚จ๊ธฐ๋„๋ก ์ง€์‹œํ•˜๋Š” ์˜ต์…˜ ํ”Œ๋ž˜๊ทธ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ์‚ฌ ํ•ด์š”

@TakoLittle : ์˜ค๋Š˜ ์šฐ๋ฆฌ๊ฐ€ ์ด๊ฒƒ์„ ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ถ€๋ถ„์ ์œผ๋กœ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ๊ตฌ์„ฑ๋˜๋Š” ๋ฐฉ์‹ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ์ˆ˜ํ•™ ํ•จ์ˆ˜ ๊ตฌ์„ฑ๊ณผ ๋™์ผํ•œ ์›์น™์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ (_f_ โˆ˜ _g_)(_x_)๋Š” _f_(_g_(_x_))๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ ์˜๋ฏธ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<strong i="7">@F</strong>
<strong i="8">@G</strong>
class X {}

๋Œ€๋žต:

F(G(X))

getter์™€ setter๋ฅผ ๋ชจ๋‘ ์žฅ์‹ํ•˜๋ฉด ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์˜ ๊ตฌ์„ฑ์ด ๋ฌด๋„ˆ์ง‘๋‹ˆ๋‹ค.

class C {
  <strong i="15">@F</strong>
  set X(value) {}

  <strong i="16">@G</strong>
  get X() {}
}

์—ฌ๊ธฐ์„œ F ๋ฐ G ๋Š” ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑ๋˜๋‚˜์š”? ์ˆœ์ „ํžˆ ๋ฌธ์„œ ์ˆœ์„œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ๋‹ˆ๊นŒ(์˜ˆ: F(G(X)) )? getter ๋ฐ setter์— ๋Œ€ํ•œ ๊ฐ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์„ธํŠธ๋Š” ๊ฐœ๋ณ„์ ์ด๋ฉฐ ๋ฌธ์„œ ์ˆœ์„œ(์˜ˆ: G(F(X)) )๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๊นŒ? get ๋ฐ set ํŠน์ • ์ˆœ์„œ๋ฅผ ์•”์‹œํ•ฉ๋‹ˆ๊นŒ(์ฆ‰, get ํ•ญ์ƒ set ์•ž์— ์žˆ๊ฑฐ๋‚˜ ๊ทธ ๋ฐ˜๋Œ€์ž„)? ์‚ฌ์šฉ์ž๋ฅผ ๋†€๋ผ๊ฒŒ ํ•˜์ง€ ์•Š๋Š” ๊ฐ€์žฅ ์ผ๊ด€๋œ ์ ‘๊ทผ ๋ฐฉ์‹์„ 100% ํ™•์‹ ํ•  ๋•Œ๊นŒ์ง€ ๋˜๋Š” ECMA-262 ๋‚ด์—์„œ ์ตœ์†Œํ•œ 2๋‹จ๊ณ„ ์ด์ƒ ์ˆ˜์šฉ ๊ฐ€๋Šฅํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ œ์•ˆ์˜ ์ผ๋ถ€์ธ ์ž˜ ๋ฌธ์„œํ™”๋œ ์ ‘๊ทผ ๋ฐฉ์‹์ด ์žˆ์„ ๋•Œ๊นŒ์ง€๋Š” ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋” ์ œํ•œ์ ์ด๊ณ  ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ˆˆ์— ๋„์ง€ ์•Š๊ณ  ๋Ÿฐํƒ€์ž„์— ์˜ˆ๊ธฐ์น˜ ์•Š์€ ๋™์ž‘์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋„์ž…ํ•˜์ง€ ์•Š๊ณ  ๋‚˜์ค‘์— ํ•ด๋‹น ์ œํ•œ์„ ์™„ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@rbuckton ์„ค๋ช… ๋„ˆ๋ฌด ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค
TSํŒ€ ์ˆ˜๊ณ ํ•˜์…จ์Šต๋‹ˆ๋‹ค!! ^^d

์ด์— ๋Œ€ํ•œ ๋ฌธ์„œ๋Š” ์–ด๋””์— ์žˆ์Šต๋‹ˆ๊นŒ? ๊ตฌํ˜„ ์ปค๋ฐ‹์„ ์—ฐ๊ฒฐํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

๊ฐ์‚ฌ ํ•ด์š”.

@mhegazy ์‚ฌ์–‘์˜ ์ตœ์‹  ๋ฒ„์ „ ๊ตฌํ˜„ ์ƒํƒœ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๋‚˜๋Š” ๊ฑฐ๊ธฐ์— ์•ฝ๊ฐ„์˜ ๋ณ€ํ™”๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” ์ œ์•ˆ์˜ ์›๋ž˜ ๋ฒ„์ „์„ ์ถ”์ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์™„๋ฃŒ๋˜์—ˆ์œผ๋ฏ€๋กœ ์ด ๋ฌธ์ œ๋ฅผ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์–‘์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์ƒˆ๋กœ์šด ๋ฌธ์ œ๋ฅผ ๊ธฐ๋กํ•˜๊ณ  ๋ชจ๋“  ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ฐ„๋žตํ•˜๊ฒŒ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ ์ œ์•ˆ์ด ์ง€๊ธˆ ์šฐ๋ฆฌ๊ฐ€ ๋›ฐ์–ด๋“ค ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ƒˆ๋กœ์šด ์ œ์•ˆ์— ๋Œ€ํ•ด @wycats ์™€ ๊ธด๋ฐ€ํžˆ ํ˜‘๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

@omeid , https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Decorators.md ์—์„œ ์„ค๋ช…์„œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@mhegazy ์—…๋ฐ์ดํŠธํ•ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ณ„์† ์ •๋ณด๋ฅผ ๋ฐ›๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์‚ฌ์–‘ ์—…๋ฐ์ดํŠธ์— ๋Œ€ํ•œ ์ƒˆ ๋ฌธ์ œ๋ฅผ ๋งŒ๋“ค ๋•Œ ์•Œ๋ฆผ์„ ๋ฐ›๊ณ  ํŒ”๋กœ์šฐํ•  ์ˆ˜ ์žˆ๋„๋ก ์—ฌ๊ธฐ์— ๋งํฌํ•˜์‹ญ์‹œ์˜ค. Aurelia ์ปค๋ฎค๋‹ˆํ‹ฐ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋ฉฐ ์—…๋ฐ์ดํŠธ ์‹œ TypeScript ๋ฐ Babel๊ณผ ๋™๊ธฐํ™”ํ•˜๊ธฐ๋ฅผ ์›ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค์‹œ ํ•œ ๋ฒˆ, TS ํŒ€์ด ํ•˜๊ณ  ์žˆ๋Š” ํ›Œ๋ฅญํ•œ ์ผ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค!

๊ธฐ๋Šฅ ์žฅ์‹์€ ๋ฌผ๋ก  ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
์ฝ”๋“œ์—์„œ ๋‹ค๋ฅธ ๊ฐœ์ฒด๋ฅผ ์žฅ์‹ํ•  ๊ณ„ํš๋„ ์žˆ์Šต๋‹ˆ๊นŒ?

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰