Dream๐Ÿฐng
article thumbnail

๐Ÿ’ [230322 TIL] Understanding TypeScript

Decorators 2๏ธโƒฃ

Decorator the synthetic sugar

ํด๋ž˜์Šค ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” constructor๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด์„œ ๊ธฐ์กด constructor๋ฅผ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.

constructor๋ฅผ ํ™•์žฅํ•  ๋•Œ super();๋Š” ๊ธฐ์กด ํด๋ž˜์Šค ํ™•์žฅ์—์„œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ธฐ์กด ํด๋ž˜์Šค์˜ ์ •๋ณด๋ฅผ ๊ธฐ์–ตํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

function ClassDeco() {
    return function<T extneds {new(...args: any[]): {name: string}}>(target: T) {
        return class extends target {
            constructor(..._: any[]) {
                super(); // not necessary
                /* write your code */
            }
        }
    }
}

@ClassDeco
class Person {
    name = 'Shou';
    
    get name() {
        return this.name;
    }
    
    constructor() {
        console.log('Creating person object...');
    }
    
    getName(intro: string) {
        console.log(intro, this.name);
    }
}

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

 

์•ก์„ธ์„œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ, ๋ฉ”์†Œ๋“œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” descriptor๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด์„œ descriptor์˜ ์†์„ฑ์„ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

function AccessorDeco(
    target: any,
    propertyKey: string | Symbol,
    descriptor: PropertyDescriptor
): ProretyDescriptor {
    return {configurable: false};
}

function MethodDeco(
    target: any,
    propertyKey: string | Symbol,
    descriptor: PropertyDescriptor
): PropertyDescriptor {
    return {enumerable: true};
}

class Person {
    name = 'Shou';
    
    @AccessorDeco
    get name() {
        return this.name;
    }
    
    constructor() {
        console.log('Creating person object...');
    }
    
    @MethodDeco
    getName(intro: string) {
        console.log(intro, this.name);
    }
}

 

Autobind decorator

๋ฉ”์†Œ๋“œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์˜ˆ์‹œ

class Printer {
    message = 'This works!';
    
    showMessage() {
        console.log(this.message);
    }
}

const printer = new Printer();

const button = document.querySelector('button');
button.addEventListener('click', printer.showMessage);
// undefined

์œ„ ์ฝ”๋“œ์—์„œ ๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ, This works!๊ฐ€ ์•„๋‹ˆ๋ผ undefined๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค.

ํด๋ฆญ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ง€์ •ํ•œ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๋Š”๋ฐ,

๊ทธ ํ•จ์ˆ˜ ์•ˆ์— ์žˆ๋Š” this๊ฐ€ printer.showMessage()๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ์˜ this์™€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.


printer.showMessage()์—์„œ์˜ this๋Š” Printer ํด๋ž˜์Šค๋ฅผ ์ฐธ์กฐํ•˜์ง€๋งŒ
button.addEventListner('click', printer.showMessage)์—์„œ์˜ this๋Š” ์ด๋ฒคํŠธ ๋Œ€์ƒ์ธ ๋ฒ„ํŠผ์„ ์ฐธ์กฐํ•œ๋‹ค.
addEventListener๊ฐ€ this๋ฅผ ์ด๋ฒคํŠธ์˜ ๋Œ€์ƒ๊ณผ ๋ฐ”์ธ๋”ฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—!
button.addEventListener('click', printer.showMessage.bind(printer));
// This works!

์ด ๊ฒฝ์šฐ ์œ„์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด This works!๊ฐ€ ์ถœ๋ ฅ๋˜์ง€๋งŒ ์ด๋ฅผ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ด์šฉํ•ด this๊ฐ€ ์ž๋™์œผ๋กœ ๋ฐ”์ธ๋”ฉ๋˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

 

function Autobind(
    _: any,
    _2: string,
    descriptor: PropertyDescriptor
) {
    const original = descriptor.value;
    const adjusted: PropertyDescriptor = {
        configurable: true,
        enumerable: false,
        /* ์‚ฌ์šฉ์ž๊ฐ€ ์ด ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผ ์‹œ๋„ํ•  ๋•Œ ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์ด๋‚˜ ํ•จ์ˆ˜๊ฐ€ ์ง์ ‘ ์‹คํ–‰๋˜์ง€ ์•Š๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•จ */
        get() {
            const bound = original.bind(this);
            return bound;
        }
    };
    return adjusted;
}

class Printer {
    message = 'This works!';
    
    @Autobind
    showMessage() {
        console.log(this.message);
    }
}

const button = document.querySelector('button');
button.addEventListener('click', printer.showMessage);
// This works!

getter๋Š” ์‹คํ–‰๋˜๊ณ  ์žˆ๋Š” ํ•จ์ˆ˜, ๊ทธ๊ฒƒ์ด ์†ํ•œ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๊ธฐ ๋•Œ๋ฌธ์—

getter์—์„œ bindํ•œ this๋Š” ์›๋ž˜ ์ •์˜ํ•œ ๋ฉ”์†Œ๋“œ์— ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•œ๋‹ค.

 

๊ทธ๋Ÿฌ๋ฏ€๋กœ Autobind ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ showMessage ๋ฉ”์†Œ๋“œ์— ์žฅ์‹ํ•˜๋ฉด

์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ์—์„œ bind๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์•„๋„ ์ž๋™์œผ๋กœ Printer ํด๋ž˜์Šค์˜ message๋ฅผ bindํ•œ๋‹ค!

 

'๐Ÿ“ Study > TypeScript' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[TS] Project Drag & Drop 1๏ธโƒฃ  (2) 2023.03.27
[TS] Decorators 3๏ธโƒฃ  (0) 2023.03.24
[TS] Decorators 1๏ธโƒฃ  (1) 2023.03.20
[TS] Generics 2๏ธโƒฃ  (0) 2023.03.17
[TS] Generics 1๏ธโƒฃ  (4) 2023.03.16
profile

Dream๐Ÿฐng

@shoupeach

๐Ÿฐ Happy new rabbit! ๐Ÿฐ

profile on loading

Loading...