# ๐Ÿ“„ Item06 ~ 10


# Item06. ํŽธ์ง‘๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํƒ€์ž… ์‹œ์Šคํ…œ ํƒ์ƒ‰ํ•˜๊ธฐ

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

  • ์˜ค๋ฅ˜ ํŒŒ์•… ์˜ˆ์‹œ
function getElement(elOrId: string | HTMLElement | null): HTMLElement {
  if (typeof elOrId === 'object') {
    return elOrId; // 'HTMLElement | null' ํ˜•์‹์€ 'HTMLElement' ํ˜•์‹์— ํ• ๋‹นํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  } else if (elOrId === null) {
    return document.body;
  } else {
    const el = document.getElementById(elOrId);
    return el; // 'HTMLElement | null' ํ˜•์‹์€ 'HTMLElement' ํ˜•์‹์— ํ• ๋‹นํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  }
}
  • ์œ„ ์˜ˆ์ œ์—์„œ ์ฒซ ๋ฒˆ์งธ ๋ถ„๊ธฐ ์ฒ˜๋ฆฌ๋ฌธ์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ์ด์œ ๋Š” typeof null๋„ "object" ์ด๋ฏ€๋กœ elOrId๋Š” ์—ฌ์ „ํžˆ ํ•ด๋‹น ๋ถ„๊ธฐ๋ฌธ ๋‚ด์—์„œ null ์ผ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค.
    • ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ฒ˜์Œ์— null ์ฒดํฌ๋ฅผ ์ถ”๊ฐ€ํ•ด์„œ ๋ฐ”๋กœ์žก์•„์•ผ ํ•œ๋‹ค.
  • ๋‘ ๋ฒˆ์งธ ์˜ค๋ฅ˜๋Š” document.getElementById๊ฐ€ ์—ฌ์ „ํžˆ null์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฒซ ๋ฒˆ์งธ ์˜ค๋ฅ˜์™€ ๋™์ผํ•˜๊ฒŒ null ์ฒดํฌ๋ฅผ ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

  • ํƒ€์ž… ์„ ์–ธ(d.ts ํŒŒ์ผ)์€ ์ฒ˜์Œ์—๋Š” ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต์ง€๋งŒ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋ฌด์—‡์„ ํ•˜๋Š”์ง€, ์–ด๋–ป๊ฒŒ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋ชจ๋ธ๋ง๋˜์—ˆ๋Š”์ง€, ์–ด๋–ป๊ฒŒ ์˜ค๋ฅ˜๋ฅผ ์ฐพ์•„๋‚ผ์ง€ ์‚ดํŽด๋ณผ ์ˆ˜ ์žˆ๋Š” ํ›Œ๋ฅญํ•œ ์ˆ˜๋‹จ์ด ๋œ๋‹ค.

# Item07. ํƒ€์ž…์ด ๊ฐ’๋“ค์˜ ์ง‘ํ•ฉ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๊ธฐ

  • ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „, ์ฆ‰ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์˜ค๋ฅ˜๋ฅผ ์ฒดํฌํ•˜๋Š” ์ˆœ๊ฐ„์—๋Š” 'ํƒ€์ž…'์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
    • 'ํ• ๋‹น ๊ฐ€๋Šฅํ•œ ๊ฐ’๋“ค์˜ ์ง‘ํ•ฉ'์ด ํƒ€์ž…์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.
    • ์ด ์ง‘ํ•ฉ์€ ํƒ€์ž…์˜ '๋ฒ”์œ„'๋ผ๊ณ  ๋ถ€๋ฅด๊ธฐ๋„ ํ•œ๋‹ค.

  • ๊ฐ€์žฅ ์ž‘์€ ์ง‘ํ•ฉ์€ ์•„๋ฌด ๊ฒƒ๋„ ํฌํ•จํ•˜์ง€ ์•Š๋Š” ๊ณต์ง‘ํ•ฉ์ด๋ฉฐ, ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” never ํƒ€์ž…์ด๋‹ค.

    • ์ด ํƒ€์ž…์œผ๋กœ ์„ ์–ธ๋œ ๋ณ€์ˆ˜์˜ ๋ฒ”์œ„๋Š” ๊ณต์ง‘ํ•ฉ์ด๋ฏ€๋กœ ์•„๋ฌด๋Ÿฐ ๊ฐ’๋„ ํ• ๋‹นํ•  ์ˆ˜ ์—†๋‹ค.
  • ์œ ๋‹› ํƒ€์ž…(๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…) : never ํƒ€์ž… ๋‹ค์Œ์œผ๋กœ ์ž‘์€ ์ง‘ํ•ฉ์ธ ํ•œ ๊ฐ€์ง€ ๊ฐ’๋งŒ ํฌํ•จํ•˜๋Š” ํƒ€์ž…

  • ์œ ๋‹ˆ์˜จ ํƒ€์ž… : ๊ฐ’ ์ง‘ํ•ฉ๋“ค์˜ ํ•ฉ์ง‘ํ•ฉ์„ ์˜๋ฏธํ•˜๋ฉฐ ํƒ€์ž…๋“ค์„ |์œผ๋กœ ๋ฌถ์–ด์ค€๋‹ค.

  • 'ํ• ๋‹น ๊ฐ€๋Šฅํ•œ'์˜ ์˜๋ฏธ

    • ์ง‘ํ•ฉ์˜ ๊ด€์ ์—์„œ, '~์˜ ์›์†Œ(๊ฐ’๊ณผ ํƒ€์ž…์˜ ๊ด€๊ณ„)' ๋˜๋Š” '~์˜ ๋ถ€๋ถ„์ง‘ํ•ฉ(๋‘ ํƒ€์ž…์˜ ๊ด€๊ณ„)'์„ ์˜๋ฏธ
  • ์ง‘ํ•ฉ์˜ ๊ด€์ ์—์„œ, ํƒ€์ž… ์ฒด์ปค์˜ ์ฃผ์š” ์—ญํ• ์€ ํ•˜๋‚˜์˜ ์ง‘ํ•ฉ์ด ๋‹ค๋ฅธ ์ง‘ํ•ฉ์˜ ๋ถ€๋ถ„ ์ง‘ํ•ฉ์ธ์ง€ ๊ฒ€์‚ฌํ•˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

  • ์ธํ„ฐ์„น์…˜ ํƒ€์ž… : ๋‘ ํƒ€์ž…์˜ ๊ต์ง‘ํ•ฉ์„ ์˜๋ฏธํ•˜๋ฉฐ & ์—ฐ์‚ฐ์ž๋กœ ์ด์–ด์ค€๋‹ค.

interface Person {
  name: string;
}

interface Lifespan {
  birth: Date;
  death?: Date;
}

type PersonSpan = Person & Lifespan;

const ps: PersonSpan = {
  name: 'abc',
  birth: new Date('1910/01/01'),
  death: new Date('1966/12/21'),
}; // ์ •์ƒ
  • ๋‹น์—ฐํžˆ ์•ž์˜ ์„ธ ๊ฐ€์ง€๋ณด๋‹ค ๋” ๋งŽ์€ ์†์„ฑ์„ ๊ฐ€์ง€๋Š” ๊ฐ’๋„ PersonSpan ํƒ€์ž…์— ์†ํ•œ๋‹ค.
keyof (A & B) = (keyof A) | (keyof B)
keyof (A | B) = (keyof A & keyof B)

  • ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” ์ธํ„ฐ์„น์…˜๋ณด๋‹ค extends ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํƒ€์ž…์„ ์„ ์–ธํ•œ๋‹ค.
interface Person {
  name: string;
}

interface PersonSpan extends Person {
  birth: Date;
  death?: Date;
}
  • extends ์˜ ์˜๋ฏธ๋Š” '~์— ํ• ๋‹น ๊ฐ€๋Šฅํ•œ'๊ณผ ๋น„์Šทํ•˜๊ฒŒ, '~์˜ ๋ถ€๋ถ„ ์ง‘ํ•ฉ'์ด๋ผ๋Š” ์˜๋ฏธ๋กœ ๋ฐ›์•„๋“ค์ผ ์ˆ˜ ์žˆ๋‹ค.
  • extends ํ‚ค์›Œ๋“œ๋Š” ์ œ๋„ค๋ฆญ ํƒ€์ž…์—์„œ ํ•œ์ •์ž๋กœ๋„ ์“ฐ์ด๋ฉฐ, ์ด ๋ฌธ๋งฅ์—์„œ๋Š” '~์˜ ๋ถ€๋ถ„ ์ง‘ํ•ฉ'์„ ์˜๋ฏธํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

  • keyof๋ฅผ ํ†ตํ•ด ํ• ๋‹น๊ณผ ์ƒ์† ๊ด€๊ณ„ ์‚ดํŽด๋ณด๊ธฐ
interface Point {
  x: number;
  y: number;
}

type PointKeys = keyof Point; // ํƒ€์ž…์€ "x" | "y"

function sortBy<K extends keyof T, T>(vals: T[], key: K): T[] {
  // ...
}

const pts: Point[] = [
  { x: 1, y: 1 },
  { x: 2, y: 0 },
];

sortBy(pts, 'x'); // ์ •์ƒ, 'x'๋Š” 'x' | 'y'๋ฅผ ์ƒ์† (์ฆ‰, keyof T)
sortBy(pts, 'y'); // ์ •์ƒ, 'y'๋Š” 'x' | 'y'๋ฅผ ์ƒ์†
sortBy(pts, Math.randomm() < 0.5 ? 'x' : 'y'); // ์ •์ƒ, 'x' | 'y๋Š” 'x' | 'y'๋ฅผ ์ƒ์†
sortBy(pts, 'z'); // '"z"' ํ˜•์‹์˜ ์ธ์ˆ˜๋Š” '"x" | "y"' ํ˜•์‹์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์— ํ• ๋‹น๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

  • ํƒ€์ž…์ด ์ง‘ํ•ฉ์ด๋ผ๋Š” ๊ด€์ ์„ ๋ฐฐ์—ด๊ณผ ํŠœํ”Œ์˜ ๊ด€๊ณ„ ์—ญ์‹œ ๋ช…ํ™•ํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค.
const triple: [number, number, number] = [1, 2, 3];
const double: [number, number] = triple;
// '[number, number, number]' ํ˜•์‹์€
// '[number, number]' ํ˜•์‹์— ํ• ๋‹นํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
// 'length' ์†์„ฑ์˜ ํ˜•์‹์ด ํ˜ธํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
// '3' ํ˜•์‹์€ '2' ํ˜•์‹์— ํ• ๋‹นํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ์Œ์—์„œ ๊ธธ์ด๋ฅผ ์ฒดํฌํ•˜๋Š” ๊ฒƒ์€ ํ•ฉ๋ฆฌ์ ์ด๋ฉฐ, ์ด๋ณด๋‹ค ๋‚˜์€ ๋ฐฉ๋ฒ•์€ ์—†์„ ๊ฒƒ์ด๋‹ค.

๐Ÿ’ก ๊ฒฐ๋ก !

ํƒ€์ž…์„ ๊ฐ’์˜ ์ง‘ํ•ฉ์œผ๋กœ ์ƒ๊ฐํ•˜๋ฉด ์ดํ•ดํ•˜๊ธฐ ํŽธํ•˜๊ณ  '์ƒ์†', 'ํ• ๋‹น ๊ฐ€๋Šฅ', '์„œ๋ธŒ ํƒ€์ž…'์€ '๋ถ€๋ถ„ ์ง‘ํ•ฉ'๊ณผ ๊ฐ™์€ ์˜๋ฏธ๋กœ ๋ฐ›์•„๋“ค์ด๋ฉด ํŽธํ•˜๋‹ค.


# Item08. ํƒ€์ž… ๊ณต๊ฐ„๊ณผ ๊ฐ’ ๊ณต๊ฐ„์˜ ์‹ฌ๋ฒŒ ๊ตฌ๋ถ„ํ•˜๊ธฐ

interface Cylinder {
  radius: number;
  height: number;
}

const Cylinder = (radius: number, height: number) => ({ radius, height });
  • interface Cylinder์—์„œ Cylinder๋Š” ํƒ€์ž…์œผ๋กœ ์“ฐ์ด๊ณ , const Cylinder์—์„œ Cylinder๋Š” ์ด๋ฆ„์€ ๊ฐ™์ง€๋งŒ ๊ฐ’์œผ๋กœ ์“ฐ์ด๋ฉฐ, ์„œ๋กœ ์•„๋ฌด๋Ÿฐ ๊ด€๋ จ๋„ ์—†๋‹ค.
    • ์ƒํ™ฉ์— ๋”ฐ๋ผ Cylinder๋Š” ํƒ€์ž…์œผ๋กœ ์“ฐ์ผ ์ˆ˜๋„ ์žˆ๊ณ , ๊ฐ’์œผ๋กœ ์“ฐ์ผ ์ˆ˜๋„ ์žˆ๋‹ค.
function calculateVolume(shape: unknown) {
  if (shape instanceof Cylinder) {
    console.log(shape.radius); // '{}' ํ˜•์‹์— 'radius' ์†์„ฑ์ด ์—†์Šต๋‹ˆ๋‹ค.
  }
}
  • ํ•˜์ง€๋งŒ ์œ„ ์ฝ”๋“œ์™€ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ณค ํ•œ๋‹ค.
    • instanceof๋ฅผ ์ด์šฉํ•ด shape๊ฐ€ Cylinder ํƒ€์ž…์ธ์ง€ ์ฒดํฌํ•˜๋ ค๊ณ  ํ•˜๋Š” ๊ตฌ๋ฌธ์ธ๋ฐ, instancof๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋Ÿฐํƒ€์ž„ ์—ฐ์‚ฐ์ž์ด๊ณ , ๊ฐ’์— ๋Œ€ํ•ด์„œ ์—ฐ์‚ฐ์„ ํ•œ๋‹ค.
    • ๊ทธ๋ž˜์„œ instanceof Cylinder๋Š” ํƒ€์ž…์ด ์•„๋‹ˆ๋ผ ํ•จ์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๊ฒŒ ๋œ๋‹ค.

  • class์™€ enum์€ ์ƒํ™ฉ์— ๋”ฐ๋ผ ํƒ€์ž…๊ณผ ๊ฐ’ ๋‘ ๊ฐ€์ง€ ๋ชจ๋‘ ๊ฐ€๋Šฅํ•œ ์˜ˆ์•ฝ์–ด์ด๋‹ค.
class Cylinder {
  radius = 1;
  height = 1;
}

function calculateVolume(shape: unknown) {
  if (shape instanceof Cylinder) {
    console.log(shape); // ์ •์ƒ, ํƒ€์ž…์€ Cylinder
    console.log(shape.raidus); // ์ •์ƒ, ํƒ€์ž…์€ number
  }
}
  • ํด๋ž˜์Šค๊ฐ€ ํƒ€์ž…์œผ๋กœ ์“ฐ์ผ ๋•Œ๋Š” ํ˜•ํƒœ(์†์„ฑ๊ณผ ๋ฉ”์„œ๋“œ)๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ˜๋ฉด, ๊ฐ’์œผ๋กœ ์“ฐ์ผ ๋Œ€๋Š” ์ƒ์„ฑ์ž๊ฐ€ ์‚ฌ์šฉ๋œ๋‹ค.

  • typeof๋„ ํƒ€์ž…๊ณผ ๊ฐ’์—์„œ ์“ฐ์ผ ๋•Œ ์„œ๋กœ ๋‹ค๋ฅธ ๊ธฐ๋Šฅ์„ ํ•œ๋‹ค.
type T1 = typeof p; // ํƒ€์ž…์€ Person
type T2 = typeof email; // ํƒ€์ž…์€ (p: Person, subject: string, body: string) => Response

const v1 = typeof p; // ๊ฐ’์€ "object"
const v2 = typeof email; // ๊ฐ’์€ "function"

const v = typeof Cylinder; // ๊ฐ’์ด "function"
type T = typeof Cylinder; // ํƒ€์ž…์ด typeof Cylinder(Cylinder๊ฐ€ ์ธ์Šคํ„ด์Šค์˜ ํƒ€์ž…์ด ์•„๋‹ˆ๋ผ ์‹ค์ œ๋กœ๋Š” new ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋ณผ ์ˆ˜ ์žˆ๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜์ด๋‹ค.)
  • ํƒ€์ž…์˜ ๊ด€์ 

    • ๊ฐ’์„ ์ฝ์–ด์„œ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์˜ ํƒ€์ž…์„ ๋ฐ˜ํ™˜
    • ํƒ€์ž… ๊ณต๊ฐ„์˜ typeof๋Š” ๋ณด๋‹ค ํฐ ํƒ€์ž…์˜ ์ผ๋ถ€๋ถ„์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , type ๊ตฌ๋ฌธ์œผ๋กœ ์ด๋ฆ„์„ ๋ถ™์ด๋Š” ์šฉ๋„๋กœ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ
  • ๊ฐ’์˜ ๊ด€์ 

    • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋Ÿฐํƒ€์ž„์˜ typeof ์—ฐ์‚ฐ์ž๊ฐ€ ๋œ๋‹ค.
    • ๋Œ€์ƒ ์‹ฌ๋ฒŒ์˜ ๋Ÿฐํƒ€์ž„ ํƒ€์ž…์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜
    • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—๋Š” ๊ณผ๊ฑฐ๋ถ€ํ„ฐ ์ง€๊ธˆ๊นŒ์ง€ ๋‹จ 6๊ฐœ(string, number, boolean, undefined, object, function)์˜ ๋Ÿฐํƒ€์ž„ ํƒ€์ž…๋งŒ์ด ์กด์žฌ
  • InstanceType ์ด๋ผ๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐ ํƒ€์ž…์„ ํ†ตํ•ด ์ƒ์„ฑ์ž์˜ ํƒ€์ž…๊ณผ ์ธ์Šคํ„ด์Šค ํƒ€์ž…์„ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.


  • ์†์„ฑ ์ ‘๊ทผ์ž์ธ []๋Š” ํƒ€์ž…์œผ๋กœ ์“ฐ์ผ ๋•Œ์—๋„ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.
    • ๊ทธ๋Ÿฌ๋‚˜ obj['field']์™€ obj.field๋Š” ๊ฐ’์ด ๋™์ผํ•˜๋”๋ผ๋„ ํƒ€์ž…์€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค.
    • ๋”ฐ๋ผ์„œ ํƒ€์ž…์˜ ์†์„ฑ์„ ์–ป์„ ๋•Œ์—๋Š” ๋ฐ˜๋“œ์‹œ ์ฒซ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์ธ obj['field']๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
const first: Person['first'] = p['first']; // ๋˜๋Š” ๊ฐ’ ์ž‘์„ฑ์‹œ p.first
  • ์ด ๋•Œ ์ธ๋ฑ์Šค ์œ„์น˜์—๋Š” ์œ ๋‹ˆ์˜จ ํƒ€์ž…๊ณผ ๊ธฐ๋ณธํ˜• ํƒ€์ž…์„ ํฌํ•จํ•œ ์–ด๋– ํ•œ ํƒ€์ž…์ด๋“  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
type PersonEl = Person['first' | 'last']; // ํƒ€์ž…์€ string
type Tuple = [string, number, Date];
type TupleEl = Tuple[number]; // ํƒ€์ž…์€ string | number | Date

# โž• ํƒ€์ž… ๊ณต๊ฐ„๊ณผ ๊ฐ’ ๊ณต๊ฐ„ ์‚ฌ์ด์—์„œ ๋‹ค๋ฅธ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง€๋Š” ์ฝ”๋“œ ํŒจํ„ด

  • this ํ‚ค์›Œ๋“œ
  • &, | ํ‚ค์›Œ๋“œ
    • ๊ฐ’์œผ๋กœ ์“ฐ์ด๋ฉด AND์™€ OR ์—ฐ์‚ฐ
    • ํƒ€์ž…์œผ๋กœ ์“ฐ์ด๋ฉด ์ธํ„ฐ์„น์…˜ ํƒ€์ž…๊ณผ ์œ ๋‹ˆ์˜จ ํƒ€์ž…
  • const๋Š” ์ƒˆ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜์ง€๋งŒ, as const๋Š” ๋ฆฌํ„ฐ๋Ÿด ๋˜๋Š” ๋ฆฌํ„ฐ๋Ÿด ํ‘œํ˜„์‹์˜ ์ถ”๋ก ๋œ ํƒ€์ž…์„ ๋ฐ”๊ฟˆ
  • extends ํ‚ค์›Œ๋“œ
    • ์„œ๋ธŒ ํด๋ž˜์Šค(class A extends B) ๋˜๋Š” ์„œ๋ธŒํƒ€์ž…(interface A extends B) ๋˜๋Š” ์ œ๋„ค๋ฆญ ํƒ€์ž…์˜ ํ•œ์ •์ž(Generic<T extends number>)๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Œ
  • in ํ‚ค์›Œ๋“œ
    • ๊ฐ’์œผ๋กœ ์“ฐ์ด๋ฉด ๋ฃจํ”„(for (key in object))
    • ํƒ€์ž…์œผ๋กœ ์“ฐ์ด๋ฉด ๋งคํ•‘๋œ(mapped) ํƒ€์ž…

# โš ๏ธ ๊ตฌ์กฐ ๋ถ„ํ•ด ๋ฌธ๋ฒ• ์‚ฌ์šฉ์‹œ ์ฃผ์˜ํ•˜์ž

function email(options: {person: Person, subject: string, body: string}) {}
// ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๊ตฌ์กฐ ๋ถ„ํ•ด ๋ฌธ๋ฒ• ์‚ฌ์šฉ์‹œ
function email({email, subject, body}) {}
// ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์—์„œ ๊ตฌ์กฐ ๋ถ„ํ•ด ๋ฌธ๋ฒ• ์ž˜๋ชป ์‚ฌ์šฉํ•œ ์˜ˆ์‹œ
function email({
  person: Person, // ๋ฐ”์ธ๋”ฉ ์š”์†Œ 'Person'์— ์•”์‹œ์ ์œผ๋กœ 'any' ํ˜•์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  subject: string, // 'string' ์‹๋ณ„์ž๊ฐ€ ์ค‘๋ณต๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”์ธ๋”ฉ ์š”์†Œ 'string'์— ์•”์‹œ์ ์œผ๋กœ 'any' ํ˜•์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  body: string, // 'string' ์‹๋ณ„์ž๊ฐ€ ์ค‘๋ณต๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”์ธ๋”ฉ ์š”์†Œ 'string'์— ์•”์‹œ์ ์œผ๋กœ 'any' ํ˜•์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค.
})
  • ๊ฐ’์˜ ๊ด€์ ์—์„œ Person๊ณผ string์ด ํ•ด์„๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.
    • Person์ด๋ผ๋Š” ๋ณ€์ˆ˜๋ช…๊ณผ string์ด๋ผ๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง€๋Š” ๋‘ ๊ฐœ์˜ ๋ณ€์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๋ คํ•œ ๊ฒƒ์ด๋‹ค.
    • ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ํƒ€์ž…๊ณผ ๊ฐ’์„ ๊ตฌ๋ถ„ํ•ด์•ผ ํ•œ๋‹ค.
// ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์—์„œ ๊ตฌ์กฐ ๋ถ„ํ•ด ๋ฌธ๋ฒ•์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•œ ์˜ˆ์‹œ
function email({person, subject, body}: {person: Person, subject: string, body: string}) {}


# Item09. ํƒ€์ž… ๋‹จ์–ธ๋ณด๋‹ค๋Š” ํƒ€์ž… ์„ ์–ธ์„ ์‚ฌ์šฉํ•˜๊ธฐ

# (1) ํƒ€์ž… ์„ ์–ธ๊ณผ ํƒ€์ž… ๋‹จ์–ธ

interface Person {
  name: string;
}

const alice: Person = { name: 'Alice' }; // ํƒ€์ž… ์„ ์–ธ
const bob = { name: 'Bob' } as Person; // ํƒ€์ž… ๋‹จ์–ธ
  • ํƒ€์ž… ๋‹จ์–ธ๋ณด๋‹ค๋Š” ํƒ€์ž… ์„ ์–ธ์„ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ๋‚ซ๋‹ค.
const alice: Person = {}; // 'Person' ์œ ํ˜•์— ํ•„์š”ํ•œ 'name' ์†์„ฑ์ด '{}' ์œ ํ˜•์— ์—†์Šต๋‹ˆ๋‹ค.
const bob = {} as Person; // ์˜ค๋ฅ˜ ์—†์Œ
  • ํƒ€์ž… ์„ ์–ธ์€ ํ• ๋‹น๋˜๋Š” ๊ฐ’์ด ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ์กฑํ•˜๋Š”์ง€ ๊ฒ€์‚ฌํ•œ๋‹ค.
  • ํƒ€์ž… ๋‹จ์–ธ์€ ๊ฐ•์ œ๋กœ ํƒ€์ž…์„ ์ง€์ •ํ–ˆ์œผ๋‹ˆ ํƒ€์ž… ์ฒด์ปค์—๊ฒŒ ์˜ค๋ฅ˜๋ฅผ ๋ฌด์‹œํ•˜๋ผ๊ณ  ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
  • ํƒ€์ž… ๋‹จ์–ธ์ด ๊ผญ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด, ์•ˆ์ „์„ฑ ์ฒดํฌ๋„ ๋˜๋Š” ํƒ€์ž… ์„ ์–ธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

# (2) ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์˜ ํƒ€์ž… ์„ ์–ธ

const people = ['alice', 'bob', 'jan'].map(
  (name): Person => ({name});
); // ํƒ€์ž…์€ Person[]
  • ์œ„ ์ฝ”๋“œ์—์„œ ์†Œ๊ด„ํ˜ธ๋Š” ๋งค์šฐ ์ค‘์š”ํ•œ ์˜๋ฏธ๋ฅผ ์ง€๋‹Œ๋‹ค.
    • (name): Person์€ name์˜ ํƒ€์ž…์ด ์—†๊ณ , ๋ฐ˜ํ™˜ ํƒ€์ž…์ด Person์ด๋ผ๊ณ  ๋ช…์‹œํ•œ๋‹ค.
    • ๊ทธ๋Ÿฌ๋‚˜ (name: Person)์€ name์˜ ํƒ€์ž…์ด Person์ž„์„ ๋ช…์‹œํ•˜๊ณ  ๋ฐ˜ํ™˜ ํƒ€์ž…์€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
// ์›ํ•˜๋Š” ๋ฐ˜ํ™˜ ํƒ€์ž…๊นŒ์ง€ ๋ช…์‹œํ•œ ๋ฒ„์ „
const people: Person[] = ['alice', 'bob', 'jan'].map(
  (name): Person => ({name});
);

๋‹จ, ํ•จ์ˆ˜ ํ˜ธ์ถœ ์ฒด์ด๋‹์ด ์—ฐ์†๋˜๋Š” ๊ณณ์—์„œ๋Š” ์ฒด์ด๋‹ ์‹œ์ž‘์—์„œ๋ถ€ํ„ฐ ๋ช…๋ช…๋œ ํƒ€์ž…์„ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค.

๊ทธ๋ž˜์•ผ ์ •ํ™•ํ•œ ๊ณณ์— ์˜ค๋ฅ˜๊ฐ€ ํ‘œ์‹œ๋œ๋‹ค.


# (3) ํƒ€์ž… ๋‹จ์–ธ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ

  • ํƒ€์ž… ์ฒด์ปค๊ฐ€ ์ถ”๋ก ํ•œ ํƒ€์ž…๋ณด๋‹ค ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ํŒ๋‹จํ•œ ํƒ€์ž…์ด ๋” ์ •ํ™•ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.
document.querySelector('#myButton').addEventListener('click', e => {
  e.currentTarget; // ํƒ€์ž…์€ EventTarget
  const button = e.currentTarget as HTMLButtonElement;
  button; // ํƒ€์ž…์€ HTMLButtonElement
})
  • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” DOM์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— #myButton์ด ๋ฒ„ํŠผ ์—˜๋ฆฌ๋จผํŠธ์ธ์ง€ ์•Œ์ง€ ๋ชปํ•œ๋‹ค.
  • ๊ทธ๋ฆฌ๊ณ  ์ด๋ฒคํŠธ์˜ currentTarget์ด ๊ฐ™์€ ๋ฒ„ํŠผ์ด์–ด์•ผ ํ•˜๋Š” ๊ฒƒ๋„ ์•Œ์ง€ ๋ชปํ•œ๋‹ค.
  • ๊ฐœ๋ฐœ์ž๋Š” ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์•Œ์ง€ ๋ชปํ•˜๋Š” ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์—ฌ๊ธฐ์„œ๋Š” ํƒ€์ž… ๋‹จ์–ธ์„ ์“ฐ๋Š” ๊ฒƒ์ด ํƒ€๋‹นํ•˜๋‹ค.

# (4) non-null assertion

const elNull = document.getElementById('foo'); // ํƒ€์ž…์€ HTMLElement | null
const el = document.getElementById('foo')!; // ํƒ€์ž…์€ HTMLElement
  • ์ ‘๋ฏธ์‚ฌ๋กœ ์“ฐ์ธ !๋ฅผ ํ†ตํ•ด ํƒ€์ž… ์ฒด์ปค๋Š” ์•Œ์ง€ ๋ชปํ•˜์ง€๋งŒ ๊ทธ ๊ฐ’์ด null์ด ์•„๋‹ˆ๋ผ๊ณ  ํ™•์‹ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
    • ๋งŒ์•ฝ ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด, null์ธ ๊ฒฝ์šฐ๋ฅผ ์ฒดํฌํ•˜๋Š” ์กฐ๊ฑด๋ฌธ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

# (5) unknown ํƒ€์ž… ๋‹จ์–ธ

  • A๊ฐ€ B์˜ ๋ถ€๋ถ„ ์ง‘ํ•ฉ์ธ ๊ฒฝ์šฐ์— ํƒ€์ž… ๋‹จ์–ธ๋ฌธ์„ ์‚ฌ์šฉํ•ด ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ด๋Ÿฌํ•œ rule์„ ์ง€ํ‚ค์ง€ ์•Š๋Š”๋‹ค๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๋ฐ ์ด ๋•Œ unknown ํƒ€์ž…์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ชจ๋“  ํƒ€์ž…์€ unknown์˜ ์„œ๋ธŒํƒ€์ž…์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด ํƒ€์ž…์ด ํฌํ•จ๋œ ๋‹จ์–ธ๋ฌธ์„ ํ•ญ์ƒ ๋™์ž‘ํ•œ๋‹ค.
  • unknown ๋‹จ์–ธ์€ ์ž„์˜์˜ ํƒ€์ž… ๊ฐ„์— ๋ณ€ํ™˜์„ ๊ฐ€๋Šฅ์ผ€ ํ•˜์ง€๋งŒ, unknown์„ ์‚ฌ์šฉํ•œ ์ด์ƒ ์ ์–ด๋„ ๋ฌด์–ธ๊ฐ€ ์œ„ํ—˜ํ•œ ๋™์ž‘์„ ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฑธ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

# Item10. ๊ฐ์ฒด ๋ž˜ํผ ํƒ€์ž… ํ”ผํ•˜๊ธฐ

  • 'primitive'.charAt(3);์™€ ๊ฐ™์€ ์ฝ”๋“œ์—์„œ charAt์€ string์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์•„๋‹ˆ๋ฉด, string์„ ์‚ฌ์šฉํ•  ๋•Œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋‚ด๋ถ€์ ์œผ๋กœ ๋งŽ์€ ๋™์ž‘์ด ์ผ์–ด๋‚œ๋‹ค.
    • string ๊ธฐ๋ณธํ˜•์—๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์—†์ง€๋งŒ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๋Š” String ๊ฐ์ฒด ํƒ€์ž…์ด ์ •์˜๋˜์–ด ์žˆ๋‹ค.
    • string ๊ธฐ๋ณธํ˜•์— charAt ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๊ธฐ๋ณธํ˜•์„ String ๊ฐ์ฒด๋กœ ๋ž˜ํ•‘(wrap)ํ•˜๊ณ , ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , ๋งˆ์ง€๋ง‰์— ๋ž˜ํ•‘ํ•œ ๊ฐ์ฒด๋ฅผ ๋ฒ„๋ฆฐ๋‹ค.
  • ๋‹ค๋ฅธ ๊ธฐ๋ณธํ˜•์—๋„ ๋™์ผํ•˜๊ฒŒ ๊ฐ์ฒด ๋ž˜ํผ ํƒ€์ž…์ด ์กด์žฌํ•œ๋‹ค.
    • number์—๋Š” Number, boolean์—๋Š” Boolean ๋“ฑ...
    • ์ด ๋ž˜ํผ ํƒ€์ž…๋“ค ๋•๋ถ„์— ๊ธฐ๋ณธํ˜• ๊ฐ’์— ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ์ •์  ๋ฉ”์„œ๋“œ(String.fromCharCode ๊ฐ™์€)๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ๊ทธ๋Ÿฌ๋‚˜ ๋ณดํ†ต์€ ๋ž˜ํผ ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.
  • ํƒ€์ž…์„ ์„ ์–ธํ•  ๋•Œ ๊ฐ์ฒด ๋ž˜ํผ ํƒ€์ž…์œผ๋กœ ์ž‘์„ฑํ•˜์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•˜์ž.
    • ๋Œ€๋ถ€๋ถ„์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ œ๊ณตํ•˜๋Š” ํƒ€์ž… ์„ ์–ธ์€ ์ „๋ถ€ ๊ธฐ๋ณธํ˜• ํƒ€์ž…์œผ๋กœ ๋˜์–ด ์žˆ๋‹ค.
  • ๊ธฐ๋ณธํ˜• ํƒ€์ž…์€ ๊ฐ์ฒด ๋ž˜ํผ์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” ๊ธฐ๋ณธํ˜• ํƒ€์ž…์„ ๊ฐ์ฒด ๋ž˜ํผ์— ํ• ๋‹นํ•˜๋Š” ์„ ์–ธ์„ ํ—ˆ์šฉํ•œ๋‹ค.
    • ๊ทธ๋Ÿฌ๋‚˜ ๊ธฐ๋ณธํ˜• ํƒ€์ž…์„ ๊ฐ์ฒด ๋ž˜ํผ์— ํ• ๋‹นํ•˜๋Š” ๊ตฌ๋ฌธ์€ ์˜คํ•ดํ•˜๊ธฐ ์‰ฝ๊ณ , ๊ตณ์ด ๊ทธ๋ ‡๊ฒŒ ํ•  ํ•„์š”๋„ ์—†๋‹ค.
    • ๊ทธ๋ƒฅ ๊ธฐ๋ณธํ˜• ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜์ž.