# ๐Ÿ“„ Item49 ~ 51


# Item49. ์ฝœ๋ฐฑ์—์„œ this์— ๋Œ€ํ•œ ํƒ€์ž… ์ œ๊ณตํ•˜๊ธฐ

# (1) class ๋‚ด์—์„œ์˜ this

class ResetButton {
  render() {
    return makeButton({ text: 'Reset', onClick: this.onClick });
  }
    
  onClick() {
    alert(`Reset ${this}`);
  }
}
  • ResetButton ์—์„œ onClick์„ ํ˜ธ์ถœํ•˜๋ฉด this ๋ฐ”์ธ๋”ฉ ๋ฌธ์ œ๋กœ ์ธํ•ด "Reset์ด ์ •์˜๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค"๋ผ๋Š” ๊ฒฝ๊ณ ๊ฐ€ ๋œฌ๋‹ค.
  • ์ผ๋ฐ˜์ ์ธ ํ•ด๊ฒฐ์ฑ…์€ ์ƒ์„ฑ์ž์—์„œ ๋ฉ”์„œ๋“œ์— this๋ฅผ ๋ฐ”์ธ๋”ฉ์‹œํ‚ค๋Š” ๊ฒƒ์ด๋‹ค.
class ResetButton {
  constructor() {
    this.onClick = this.onClick.bind(this);
  }
    
  render() {
    return makeButton({ text: 'Reset', onClick: this.onClick });
  }
    
  onClick() {
    alert(`Reset ${this}`);
  }
}
  • onClick๋ฉ”์†Œ๋“œ๋Š” ResetButton.prototype์˜ ์†์„ฑ์„ ์ •์˜ํ•œ๋‹ค.
    • ๊ทธ๋Ÿฌ๋ฏ€๋กœ ResetButton์˜ ๋ชจ๋“  ์ธ์Šคํ„ด์Šค์—์„œ ๊ณต์œ ๋œ๋‹ค.
  • ๊ทธ๋Ÿฌ๋‚˜ ์ƒ์„ฑ์ž์—์„œ this.onClick = ...์œผ๋กœ ๋ฐ”์ธ๋”ฉํ•˜๋ฉด, onClick ์†์„ฑ์— this๊ฐ€ ๋ฐ”์ธ๋”ฉ๋˜์–ด ํ•ด๋‹น ์ธ์Šคํ„ด์Šค์— ์ƒ์„ฑ๋œ๋‹ค.
    • ์†์„ฑ ํƒ์ƒ‰ ์ˆœ์„œ์—์„œ onClick ์ธ์Šคํ„ด์Šค ์†์„ฑ์€ onClick ํ”„๋กœํ† ํƒ€์ž… ์†์„ฑ๋ณด๋‹ค ์•ž์— ๋†“์ด๋ฏ€๋กœ, render() ๋ฉ”์„œ๋“œ์˜ this.onClick์€ ๋ฐ”์ธ๋”ฉ๋œ ํ•จ์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๊ฒŒ ๋œ๋‹ค.
  • ์กฐ๊ธˆ ๋” ๊ฐ„๋‹จํ•œ ํ•ด๊ฒฐ์ฑ…์œผ๋กœ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
class ResetButton {
  render() {
    return makeButton({ text: 'Reset', onClick: this.onClick });
  }
    
  onClick = () => {
    alert(`Reset ${this}`); // "this"๊ฐ€ ํ•ญ์ƒ ์ธ์Šคํ„ด์Šค๋ฅผ ์ฐธ์กฐํ•œ๋‹ค.
  }
}

# (2) ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์— this ๋„˜๊ธฐ๊ธฐ

  • ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์— this๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ , ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ call๋กœ ํ˜ธ์ถœํ•ด์„œ ํ•ด๊ฒฐ
function addKeyListener (
  el: HTMLElement,
  fn: (this: HTMLElement, e: KeyboardEvent) => void
) {
  el.addEventListener('keydown', e => {
    fn.call(el, e);
  });
}
  • ์‹ค ์ ์šฉ ์˜ˆ์‹œ
declare let el: HTMLElement;

// ๋งŒ์•ฝ ์ฝœ๋ฐฑ์„ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋กœ ์ž‘์„ฑํ•˜๊ณ  this๋ฅผ ์ฐธ์กฐํ•˜๋ ค๊ณ ํ•˜๋ฉด ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋ฌธ์ œ๋ฅผ ์žก์•„๋‚ผ ๊ฒƒ์ด๋‹ค.
addKeyListener(el, function(e) {
  this.innerHTML; // ์ •์ƒ, "this"๋Š” HTMLElement ํƒ€์ž…
});

  • this ๋ฐ”์ธ๋”ฉ์ด ๋™์ž‘ํ•˜๋Š” ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•ด์•ผ ํ•œ๋‹ค.
  • ์ฝœ๋ฐฑ ํ•จ์ˆ˜์—์„œ this๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ํƒ€์ž… ์ •๋ณด๋ฅผ ๋ช…์‹œํ•ด์•ผ ํ•œ๋‹ค.

# Item50. ์˜ค๋ฒ„๋กœ๋”ฉ ํƒ€์ž…๋ณด๋‹ค๋Š” ์กฐ๊ฑด๋ถ€ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๊ธฐ

function double(x: number | string): number | string;
function double(x: any) { return x + x };
  • ์œ„์™€ ๊ฐ™์ด ์„ ์–ธํ•˜๋ฉด ๋ชจํ˜ธํ•œ ๋ถ€๋ถ„์ด ์žˆ๋‹ค.
    • number ํƒ€์ž…์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋„ฃ์œผ๋ฉด number ํƒ€์ž…์„, string ํƒ€์ž…์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋„ฃ์œผ๋ฉด string ํƒ€์ž…์„ ๋ฐ˜ํ™˜ํ•˜๋‚˜ number ํƒ€์ž…์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋„ฃ๊ณ  string ํƒ€์ž…์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ๋„ ํฌํ•จ๋˜์–ด ์žˆ๋‹ค.
    • ๊ทธ๋ž˜์„œ ์ œ๋„ค๋ฆญ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋Ÿฌํ•œ ๋™์ž‘์„ ๋ชจ๋ธ๋งํ•  ์ˆ˜ ์žˆ๋‹ค.
function double<T extends number | string>(x: T): T;
function double(x: any) { return x + x };

const num = double(12); // ํƒ€์ž…์ด 12
const str = double('x'); // ํƒ€์ž…์ด "x"
  • ํƒ€์ž…์„ ๊ตฌ์ฒด์ ์œผ๋กœ ๋งŒ๋“ค์–ด ๋ณด๋ ค๋Š” ์‹œ๋„๋Š” ์ข‹์•˜์œผ๋‚˜ ๋„ˆ๋ฌด ๊ณผํ•˜๋‹ค. ํƒ€์ž…์ด ๋„ˆ๋ฌด ๊ณผํ•˜๊ฒŒ ๊ตฌ์ฒด์ ์ด๋‹ค.
    • string ํƒ€์ž…์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋„˜๊ธฐ๋ฉด string ํƒ€์ž…์ด ๋ฐ˜ํ™˜๋˜์–ด์•ผ ํ•œ๋‹ค.
  • ๊ทธ๋ž˜์„œ ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ํƒ€์ž… ์„ ์–ธ์œผ๋กœ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
function double(x: number): number;
function double(x: string): string;
function double(x: any) { return x + x };

const num = double(12); // ํƒ€์ž…์ด number
const str = double('x'); // ํƒ€์ž…์ด string
  • string์ด๋‚˜ number ํƒ€์ž…์˜ ๊ฐ’์œผ๋กœ๋Š” ์ž˜ ๋™์ž‘ํ•˜์ง€๋งŒ, ์œ ๋‹ˆ์˜จ ํƒ€์ž… ๊ด€๋ จํ•ด์„œ ๋ฌธ์ œ๊ฐ€ ์—ฌ์ „ํžˆ ๋ฐœ์ƒํ•œ๋‹ค.
  • ์˜ค๋ฒ„๋กœ๋”ฉ (string | number ํƒ€์ž…)์„ ์ถ”๊ฐ€ํ•ด์„œ ์ถ”๊ฐ€ํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๊ฐ€์žฅ ์ข‹์€ ํ•ด๊ฒฐ์ฑ…์€ **์กฐ๊ฑด๋ถ€ ํƒ€์ž…**์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
function double<T extends number | string>(
  x: T
): T extends string ? string : number;
function double(x: any) { return x + x };
  • T๊ฐ€ string์˜ ๋ถ€๋ถ„ ์ง‘ํ•ฉ์ด๋ฉด(string, ๋˜๋Š” ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด, ๋˜๋Š” ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด์˜ ์œ ๋‹ˆ์˜จ), ๋ฐ˜ํ™˜ ํƒ€์ž…์ด string์ด๋‹ค.
  • ๊ทธ ์™ธ์˜ ๊ฒฝ์šฐ๋Š” ๋ฐ˜ํ™˜ ํƒ€์ž…์ด number์ด๋‹ค.
  • ์˜ค๋ฒ„๋กœ๋”ฉ ํƒ€์ž…๋ณด๋‹ค ์กฐ๊ฑด๋ถ€ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
    • ์กฐ๊ฑด๋ถ€ ํƒ€์ž…์€ ์ถ”๊ฐ€์ ์ธ ์˜ค๋ฒ„๋กœ๋”ฉ ์—†์ด ์œ ๋‹ˆ์˜จ ํƒ€์ž…์„ ์ง€์›ํ•  ์ˆ˜ ์žˆ๋‹ค.

# Item51. ์˜์กด์„ฑ ๋ถ„๋ฆฌ๋ฅผ ์œ„ํ•ด ๋ฏธ๋Ÿฌ ํƒ€์ž… ์‚ฌ์šฉํ•˜๊ธฐ

// Buffer์˜ ํƒ€์ž… ์ •์˜๋Š” '@types/node'๋ฅผ ์„ค์น˜ํ•˜๋ฉด ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.
function parseCSV(contents: string | Buffer): {[column: string]: string}[] {
  if (typeof contents === 'object') {
    // ๋ฒ„ํผ์ธ ๊ฒฝ์šฐ
    return parseCSV(contents.toString('utf8'));
  }
  // ...
}
  • @types/node๋Š” devDependencies๋กœ ํฌํ•จํ•ด์•ผ ํ•˜๋Š”๋ฐ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋‘ ๊ทธ๋ฃน ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค.
    • @types์™€ ๋ฌด๊ด€ํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐœ๋ฐœ์ž
    • NodeJS์™€ ๋ฌด๊ด€ํ•œ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์›น ๊ฐœ๋ฐœ์ž
  • ๊ทธ๋ž˜์„œ ๊ฐ์ž๊ฐ€ ํ•„์š”ํ•œ ๋ชจ๋“ˆ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์กฐ์  ํƒ€์ดํ•‘์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
    • @types/node์— ์žˆ๋Š” Buffer ์„ ์–ธ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ํ•„์š”ํ•œ ๋ฉ”์„œ๋“œ์™€ ์†์„ฑ๋งŒ ๋ณ„๋„๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.
interface CsvBuffer {
  toString(encoding: string): string;
}

function parseCSV(contents: string | CsvBuffer): {[column: string]: string}[] {
 // ...
}
  • CsvBuffer๋Š” Buffer ์ธํ„ฐํŽ˜์ด์Šค๋ณด๋‹ค ํ›จ์”ฌ ์งง์œผ๋ฉด์„œ๋„ ์‹ค์ œ๋กœ ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ์„ ๋–ผ์–ด ๋‚ด์–ด ๋ช…์‹œํ–ˆ๋‹ค.
  • ๋งŒ์•ฝ ์ž‘์„ฑ ์ค‘์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์˜์กดํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ตฌํ˜„๊ณผ ๋ฌด๊ด€ํ•˜๊ฒŒ ํƒ€์ž…์—๋งŒ ์˜์กดํ•œ๋‹ค๋ฉด, ํ•„์š”ํ•œ ์„ ์–ธ๋ถ€๋งŒ ์ถ”์ถœํ•˜์—ฌ ์ž‘์„ฑ ์ค‘์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋„ฃ๋Š” ๊ฒƒ(๋ฏธ๋Ÿฌ๋ง, mirroring)์„ ๊ณ ๋ คํ•ด ๋ณด๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
  • ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ํƒ€์ž…์ด ์•„๋‹Œ ๊ตฌํ˜„์— ์˜์กดํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ ๋™์ผํ•œ ๊ธฐ๋ฒ•์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ณ  ํƒ€์ž… ์˜์กด์„ฑ์„ ํ”ผํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ๊ทธ๋Ÿฌ๋‚˜ ํ”„๋กœ์ ํŠธ์˜ ์˜์กด์„ฑ์ด ๋‹ค์–‘ํ•ด์ง€๊ณ  ํ•„์ˆ˜ ์˜์กด์„ฑ์ด ์ถ”๊ฐ€๋จ์— ๋”ฐ๋ผ ๋ฏธ๋Ÿฌ๋ง ๊ธฐ๋ฒ•์„ ์ ์šฉํ•˜๊ธฐ๊ฐ€ ์–ด๋ ค์›Œ์ง„๋‹ค.
    • ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ํƒ€์ž… ์„ ์–ธ์˜ ๋Œ€๋ถ€๋ถ„์„ ์ถ”์ถœํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ์ฐจ๋ผ๋ฆฌ ๋ช…์‹œ์ ์œผ๋กœ @types ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒŒ ๋‚ซ๋‹ค.