ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์™€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ด€๊ณ„

  • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์ƒ์œ„์ง‘ํ•ฉ (Superset)
  • ์ฆ‰ ๋ชจ๋“  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ (ํ•˜์ง€๋งŒ ๋ฐ˜๋Œ€๋Š” ์„ฑ๋ฆฝํ•˜์ง€ ์•Š์Œ)

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

  • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์˜ ํƒ€์ž… ์‹œ์Šคํ…œ์€ ๋Ÿฐํƒ€์ž„์— ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ฝ”๋“œ๋ฅผ ๋ฏธ๋ฆฌ ์ฐพ์•„๋‚ธ๋‹ค.

์ฝ”๋“œ ์ƒ์„ฑ๊ณผ ํƒ€์ž…์ด ๊ด€๊ณ„ ์—†์Œ์„ ์ดํ•ดํ•˜๊ธฐ

  • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๋ณ€ํ™˜ ๋  ๋•Œ, ์ฝ”๋“œ ๋‚ด์˜ ํƒ€์ž…์—๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š”๋‹ค.
  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ์‹œ์ ์—๋„ ํƒ€์ž…์€ ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š”๋‹ค.

๋Ÿฐํƒ€์ž„์—๋Š” ํƒ€์ž… ์ฒดํฌ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

interface Rectangle {
   height: number;
   width: number;
}

if(shape instanceof Rectangle) // ์˜ค๋ฅ˜!
  • ํƒ€์ž…์€ ๋Ÿฐํƒ€์ž„ ์‹œ์ ์— ์•„๋ฌด๋Ÿฐ ์—ญํ• ์„ ํ•  ์ˆ˜ ์—†๋‹ค.
  • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์˜ ํƒ€์ž…์€ ์ œ๊ฑฐ ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์‹ค์ œ๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ์ปดํŒŒ์ผ ๋˜๋Š” ๊ณผ์ •์—์„œ ๋ชจ๋“  ์ธํ„ฐํŽ˜์ด์Šค, ํƒ€์ž…, ํƒ€์ž… ๊ตฌ๋ฌธ์€ ๊ทธ๋ƒฅ ์ œ๊ฑฐ๋˜์–ด ๋ฒ„๋ฆฐ๋‹ค.

๋Ÿฐํƒ€์ž„ ํƒ€์ž…์€ ์„ ์–ธ๋œ ํƒ€์ž…๊ณผ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค.

  • ์–ด๋Š๊ฒฝ์šฐ? API ํ˜ธ์ถœ๋กœ ๋ฐ›์•„์˜จ ๊ฐ’์˜ ๊ฒฝ์šฐ

๊ตฌ์กฐ์  ํƒ€์ดํ•‘

interface Vector2D {
  x: number;
  y: number;
}

interface Vector3D {
  x: number;
  y: number;
  z: number;
}

function calculateLength(v: Vector2D) {
  return Math.sqrt(v.x * v.x + v.y * v.y);
}
  • ์œ„์— Vector3D ์—๋Š” Vector2D ํƒ€์ž…์— ์žˆ๋Š” x , y ์†์„ฑ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— calculateLength ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค.
  • ์ฆ‰, Vector3D ์˜ ๊ตฌ์กฐ๊ฐ€ Vector2D์˜ ๊ตฌ์กฐ์™€ ํ˜ธํ™˜๋˜๊ธฐ ๋•Œ๋ฌธ์—, calculateLength ํ˜ธ์ถœ์ด ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.

๋ด‰์ธ๋œ, ์ •ํ™•ํ•œ ํƒ€์ž…

  • ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•  ๋•Œ, ํ˜ธ์ถœ์— ์‚ฌ์šฉ๋˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์†์„ฑ๋“ค์ด ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ํƒ€์ž…์— ์„ ์–ธ๋œ ์†์„ฑ๋งŒ์„ ๊ฐ€์งˆ๊ฑฐ๋ผ ์ƒ๊ฐํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์œ„์—์„œ ๋ณด์•˜๋“ฏ , Vector3D ํƒ€์ž…์ด ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋“ค์–ด์˜ค๋ฉด Vector2D ํƒ€์ž…์—๋Š” ์—†๋Š” x ์†์„ฑ์ด ์ถ”๊ฐ€๋กœ ๋“ค์–ด์˜จ๋‹ค.
  • ์ด๋Ÿฌํ•œ ํƒ€์ž…์„ ๋ด‰์ธ๋œ,์ •ํ™•ํ•œ ํƒ€์ž…์ด๋ผ๊ณ  ํ•œ๋‹ค.
  • ์ด๋Š” ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์—์„œ ํ‘œํ˜„ํ•  ์ˆ˜ ์—†๋‹ค.
  • ๋”ฐ๋ผ์„œ ์•„๋ž˜์™€ ๊ฐ™์€ ์˜ˆ์‹œ๊ฐ€ ์žˆ๋‹ค.
function calculateL1(v: Vector3D) {
  let length = 0;
  for (const axis of Object.keys(v)) {
    const coord = v[axis]; //  'string' ์€ 'Vector3D'์˜ ์ธ๋ฑ์Šค๋กœ ์‚ฌ์šฉํ• ์ˆ˜ ์—†๊ธฐ์— ์—˜๋ฆฌ๋จผํŠธ๋Š” ์•”์‹œ์ ์œผ๋กœ 'any' ํƒ€์ž…์ž…๋‹ˆ๋‹ค.
  }
}
  • ์™œ ? x,y,z ์ค‘ ํ•˜๋‚˜๋‹ˆ๊นŒ string ํƒ€์ž…์ด ์•„๋‹ˆ์ง€ ์•Š์€๊ฐ€?
    • ๊ตฌ์กฐ์ ํƒ€์ดํ•‘์œผ๋กœ ์ธํ•ด v ๋Š” x,y,z ์™ธ์—๋„ ๋‹ค๋ฅธ ์†์„ฑ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ axis ํƒ€์ž…์€ string ์ด ๋  ์ˆ˜๋„ ์žˆ๋‹ค.
    • ์ฆ‰, v[axis] ๊ฐ€ ์ •ํ™•ํžˆ ์–ด๋–ค ์†์„ฑ์ด ๋  ์ง€ ์•Œ ์ˆ˜ ์—†์œผ๋ฏ€๋กœ number ๋ผ๊ณ  ํ™•์ •ํ•  ์ˆ˜ ์—†๋‹ค.
    • ์ด๋Ÿฌ๋Š” ๊ฒฝ์šฐ ๋ฃจํ”„๋ณด๋‹ค ๋ชจ๋“  ์†์„ฑ์„ ๊ฐ๊ฐ ์ฐธ์กฐํ•˜๋Š” ๊ตฌํ˜„์ด ๋” ๋‚ซ๋‹ค.

๊ตฌ์กฐ์  ํƒ€์ดํ•‘๊ณผ ๋•ํƒ€์ดํ•‘์˜ ์ฐจ์ด์ 

  • ๋•ํƒ€์ดํ•‘๊ณผ ๊ตฌ์กฐ์ ํƒ€์ดํ•‘์˜ ์ฐจ์ด์ ์€ ๋•ํƒ€์ดํ•‘์€ ๋Ÿฐํƒ€์ž„ ์‹œ, ๊ตฌ์กฐ์ ํƒ€์ดํ•‘์€ ์ปดํŒŒ์ผ ์‹œ ์ผ์–ด๋‚œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

any ํƒ€์ž… ์ง€์–‘ํ•˜๊ธฐ

  1. any ํƒ€์ž…์€ ์•ˆ์ •์„ฑ์ด ์—†๋‹ค.
  2. any๋Š” ํ•จ์ˆ˜ ์‹œ๊ทธ๋„ˆ์ณ๋ฅผ ๋ฌด์‹œํ•ด๋ฒ„๋ฆฐ๋‹ค.
  3. any ๋Š” ์–ธ์–ด ์„œ๋น„์Šค๊ฐ€ ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.
  4. any ๋Š” ์ฝ”๋“œ ๋ฆฌํŒฉํ„ฐ๋ง ๋•Œ ๋ฒ„๊ทธ๋ฅผ ๊ฐ์ถ˜๋‹ค.
  5. any ๋Š” ํƒ€์ž… ์„ค๊ณ„๋ฅผ ๊ฐ์ถ˜๋‹ค.
  6. any ๋Š” ํƒ€์ž…์‹œ์Šคํ…œ์˜ ์‹ ๋ขฐ๋„๋ฅผ ๋–จ์–ด๋œจ๋ฆฐ๋‹ค.

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

type K = keyof (Person | Lifespan); // ํƒ€์ž…์ด never
  • ์œ„์˜ ํƒ€์ž…์ด never ์ธ ์ด์œ ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
keyof (A|B) = (keyof A)& (keyof B)
keyof (A&B) = (keyof A) | (keyof B)

ํƒ€์ž… ๋‹จ์–ธ๋ณด๋‹ค ํƒ€์ž… ์„ ์–ธ ์‚ฌ์šฉํ•˜๊ธฐ

const people = ['alice', 'bob', 'jan'].map((name) => ({ name }));
// Person[] ์„ ์›ํ–ˆ์ง€๋งŒ ๊ฒฐ๊ณผ๋Š” { name: string; } []

// ํƒ€์ž… ๋‹จ์–ธ์„ ์“ฐ๋ฉด
const people = ['alice', 'bob', 'jan'].map((name) => ({ name } as Person));

// ์„ ์–ธํ•˜๊ธฐ 1๋ฒˆ
const people = ['alice', 'bob', 'jan'].map((name) => {
  const person: Person = { name };
  return person;
}); // ํƒ€์ž…์€ Person[]

// ์„ ์–ธํ•˜๊ธฐ 2๋ฒˆ (๋ฆฌํŒฉํ„ฐ๋ง)

const people = ['alice', 'bob', 'jan'].map((name): Person => ({ name }));
// ํƒ€์ž…์€ Person[]
  • 2๋ฒˆ์ด ์–ด๋–ป๊ฒŒ ๊ฐ€๋Šฅํ•œ๊ฐ€.. (name):Person ์€ name ์˜ ํƒ€์ž…์ด ์—†๊ณ  ๋ฐ˜ํ™˜ ํƒ€์ž…์ด Person ์ด๋ผ๊ณ  ๋ช…์‹œํ•œ๋‹ค.

์„ ์–ธ๋ณด๋‹ค ๋‹จ์–ธ์ด ์œ ๋ฆฌํ•œ ๊ฒฝ์šฐ

  • ํƒ€์ž… ์ฒด์ปค์˜ ์ถ”๋ก ๋ณด๋‹ค ๋‚˜์˜ ํŒ๋‹จ์ด ๋” ์ •ํ™•ํ•  ๋•Œ
  • DOM element ์— ๋Œ€ํ•ด์„œ..
  • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” DOM์— ์ ‘๊ทผ ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— DOM ํƒ€์ž…์„ ๋ชจ๋ฅธ๋‹ค.
const el = document.body as Person; // ์—๋Ÿฌ
const el = (document.body as unknown) as Person; // ์„ฑ๊ณต
  • ์ฒซ๋ฒˆ์งธ์˜ ๊ฒฝ์šฐ HTMLElement ์™€ Person ์ด ์„œ๋กœ์˜ ์„œ๋ธŒํƒ€์ž…์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณ€ํ™˜์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
  • unknown ์„ ์‚ฌ์šฉํ•˜๋ฉด, ๋™์ž‘ํ•˜๋Š”๋ฐ ๊ทธ ์ด์œ ๋Š” unknown์ด ๋ชจ๋“  ํƒ€์ž…์˜ ์„œ๋ธŒํƒ€์ž…์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

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

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

์ž‰์—ฌ ์†์„ฑ ์ฒดํฌ์˜ ํ•œ๊ณ„ ์ธ์ง€ํ•˜๊ธฐ

interface Room {
  numDoors: number;
  ceilingHeightFt: number;
}

const r:Room {
  numDoors:1,
  ceilingHeightFt:10,
  elephant: 'present'
}
// ๊ฐœ์ฒด ๋ฆฌํ„ฐ๋Ÿด์€ ์•Œ๋ ค์ง„ ์†์„ฑ๋งŒ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, Room ํ˜•์‹์— elephant ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
  • ๊ตฌ์กฐ์  ํƒ€์ž…์‹œ์Šคํ…œ์—์„œ ๋ฐœ์ƒ ํ•  ์ˆ˜ ์ž‡๋Š” ์ค‘์š”ํ•œ ์ข…๋ฅ˜์˜ ์˜ค๋ฅ˜(๋‹ค๋ฅธ ํƒ€์ž…์ด ์ถ”๊ฐ€๋˜๋Š” ๊ฒƒ)๋ฅผ ์žก์„ ์ˆ˜ ์žˆ๋„๋ก โ€˜์ž‰์—ฌ ์†์„ฑ ์ฒดํฌโ€™๋ผ๋Š” ๊ณผ์ •์ด ์ˆ˜ํ–‰๋˜์—ˆ๋‹ค.
  • ํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ์ž‰์—ฌ์†์„ฑ ์ฒดํฌ๋Š” ๋งค๋ฒˆ ์ด๋ฃจ์–ด์ง€๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

์ž‰์—ฌ ์†์„ฑ ์ฒดํฌ๊ฐ€ ์ผ์–ด๋‚˜๋Š” ๊ฒฝ์šฐ

  1. ํƒ€์ž…์ด ์„ ์–ธ๋˜์–ด ์žˆ์„ ๋•Œ, ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด๋กœ ๊ฐ’์„ ํ• ๋‹น ํ•  ๋•Œ
  2. ํƒ€์ž…์ด ์„ ์–ธ๋˜์–ด ์žˆ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜์—, ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•  ๋•Œ

์ž‰์—ฌ ์†์„ฑ ์ฒดํฌ๊ฐ€ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ

  1. ํƒ€์ž… ์„ ์–ธ๋Œ€์‹  ํƒ€์ž… ๋‹จ์–ธ์„ ์‚ฌ์šฉ ํ•  ๋•Œ
  2. ํƒ€์ž…์ด ์„ ์–ธ๋œ ๊ฐ’ ํ˜น์€ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์ด ์•„๋‹ˆ๋ผ ๋ณ€์ˆ˜๋กœ ๊ฐ’์„ ํ• ๋‹นํ•˜๋Š” ๊ฒฝ์šฐ

์ž‰์—ฌ ์†์„ฑ ์ฒดํฌ๊ฐ€ ํ•„์š”ํ•œ ๋‹จ์ ์ธ ์˜ˆ์‹œ

interface Option {
  title: string;
  darkMode?: boolean;
}

const o1: Option = document;
const o2: Option = new HTMLAnchorElement();
// ์—๋Ÿฌ ์—†์Œ
  • ์™œ o1. ๊ณผ o2 ์˜ ๊ฒฝ์šฐ ์—๋Ÿฌ๊ฐ€ ์—†์„๊นŒ?

  • ์ผ๋‹จ ์ž‰์—ฌ์†์„ฑ ์ฒดํฌ๋ฅผ ํ•˜์ง€ ๋ชปํ–ˆ๊ณ  (๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด๋กœ ๊ฐ’์„ ํ• ๋‹นํ•œ๊ฒŒ ์•„๋‹ˆ๋ฏ€๋กœ), ๊ทธ์— ๋”ฐ๋ผ์„œ document ์™€ HTMLAnchorElement ์—๋Š” string ํƒ€์ž…์ธ title ์†์„ฑ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์—!

  • ๋”ฐ๋ผ์„œ ์œ„์˜ ํ• ๋‹น๋ฌธ์€ ์ •์ƒ์ด๋‹ค.

  • ์ž‰์—ฌ ์†์„ฑ์„ ์ฒดํฌํ•จ์œผ๋กœ์จ, ๊ธฐ๋ณธ์ ์œผ๋กœ ํƒ€์ž… ์‹œ์Šคํ…œ์˜ ๊ตฌ์กฐ์  ๋ณธ์งˆ์„ ํ•ด์น˜์ง€ ์•Š์œผ๋ฉด์„œ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์— ์•Œ ์ˆ˜ ์—†๋Š” ์†์„ฑ์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š์•„์„œ ์•ž์—์„œ ๋‹ค๋ฃฌ ๋ฌธ์ œ์ ๋“ค์„ ํ•ด๊ฒฐ ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•จ์ˆ˜ ํ‘œํ˜„์‹์— ํƒ€์ž… ์ ์šฉํ•˜๊ธฐ

  • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ํ•จ์ˆ˜ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
  • ์™œ? ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ถ€ํ„ฐ ๋ฐ˜ํ™˜๊ฐ’๊นŒ์ง€ ์ „์ฒด๋ฅผ ํ•จ์ˆ˜ ํƒ€์ž…์œผ๋กœ ์„ ์–ธํ•˜์—ฌ, ํ•จ์ˆ˜ ํ‘œํ˜„์‹์— ์žฌ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
type BinaryFn = (a: number, b: number) => number;
const add: BinaryFun = (a, b) => a + b;

ํƒ€์ž…๊ณผ ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ฐจ์ด์  ์•Œ๊ธฐ

๊ณตํ†ต์ 

  1. ํƒ€์ž… ์„ ์–ธ๋œ ๋ณ€์ˆ˜์— ๊ฐ์ฒด๋ฆฌํ„ฐ๋Ÿด ํ• ๋‹น ์‹œ ์ž‰์—ฌ์†์„ฑ์„ ์ฒดํฌํ•ด์ค€๋‹ค.
  2. ์ธ๋ฑ์Šค ์‹œ๊ทธ๋‹ˆ์ณ๋ฅผ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  3. ํ•จ์ˆ˜ ํƒ€์ž…๋„ ์ •์˜ ํ•  ์ˆ˜ ์žˆ๋‹ค. (๊ทธ๋Ÿฐ๋ฐ ์ด ๊ฒฝ์šฐ๋Š” ๋Œ€๋ถ€๋ถ„ ํƒ€์ž… alias ๋ฅผ ์“ฐ๋Š”๊ฒŒ ์ข‹๋‹ค.)
  4. ์ œ๋„ค๋ฆญ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  5. ์ธํ„ฐํŽ˜์ด์Šค๋Š” ํƒ€์ž…์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํƒ€์ž…์€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ™•์žฅ ํ•  ์ˆ˜ ์žˆ๋‹ค.
// ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ํƒ€์ž… ํ™•์žฅ
interface IStateWithPop extends TState {
  population: number;
}

// ํƒ€์ž…์ด ์ธํ„ฐํŽ˜์ด์Šค ํ™•์žฅ
type TStateWithPop = IState & { population: number };
  1. ํด๋ž˜์Šค ๊ตฌํ˜„(implements) ์‹œ, ํƒ€์ž…๊ณผ ์ธํ„ฐํŽ˜์ด์Šค ๋‘˜๋‹ค ์‚ฌ์šฉ ๊ฐ€๋Šฅ

์ฐจ์ด์ 

  1. ์œ ๋‹ˆ์˜จ ํƒ€์ž…์€ ์žˆ์ง€๋งŒ ์œ ๋‹ˆ์˜จ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์—†๋‹ค.
  2. ์ธํ„ฐํŽ˜์ด์Šค๋Š” ํƒ€์ž…์„ ํ™•์žฅ(extends) ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํƒ€์ž…์€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

์œ ๋‹ˆ์˜จ ํƒ€์ž…์„ ํ™•์žฅํ•ด์•ผํ•˜๋Š”๊ฒฝ์šฐ

type Input = {};
type Output = {};

interface VariableMap {
  [name: string]: Input | Output;
}

์œ ๋‹ˆ์˜จ ํƒ€์ž…์— name ์†์„ฑ์„ ๋ถ™์ธ ํƒ€์ž… ๋งŒ๋“ค๊ธฐ

type NamedVariabel = (Input | Output) & { name: string };
  1. ํŠœํ”Œ๊ณผ ๋ฐฐ์—ดํƒ€์ž…๋„ type ํ‚ค์›Œ๋“œ๋กœ ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ํ‘œํ˜„ ๊ฐ€๋Šฅ
type Pair = [number, number];
type StringList = string[];
type NamedNums = [string, ...number[]];
  1. ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋ณด๊ฐ•(agument) ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. (์„ ์–ธ ๋ณ‘ํ•ฉ! declaration merging)


interface IState {
  name: string;
  capital: string;
}

interface IState{
  population:number;
}

const newyork : IState{
  name: 'NewYork',
  capital: 'NewYork',
  population: 500_00
}
  • ์œ„์™€ ๊ฐ™์€ ์„ ์–ธ ๋ณ‘ํ•ฉ์€ ์ฃผ๋กœ ํƒ€์ž… ์„ ์–ธ ํŒŒ์ผ์—์„œ ์‚ฌ์šฉ๋œ๋‹ค.
  • ๋”ฐ๋ผ์„œ ์„ ์–ธ ํ•ฉ์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฌด์กฐ๊ฑด interface ๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.
  • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” ์—ฌ๋Ÿฌ ๋ฒ„์ „์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์—ฌ๋Ÿฌ ํƒ€์ž…์„ ๋ชจ์•„ ๋ณ‘ํ•ฉํ•œ๋‹ค. ๋ณ‘ํ•ฉ์„ ํ†ตํ•ด์„œ Array ์ธํ„ฐํŽ˜์ด์Šค์— ์—ฌ๋Ÿฌ ๋ฉ”์„œ๋“œ๊ฐ€ ์ถ”๊ฐ€๋œ๋‹ค.
  • ๋”ฐ๋ผ์„œ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ถ”๊ฐ€๋˜๋Š” ๊ฒƒ์„ ์›์น˜ ์•Š๋Š”๋‹ค๋ฉด, ์ธํ„ฐํŽ˜์ด์Šค ๋Œ€์‹  ํƒ€์ž…์„ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.

ํƒ€์ž… ์—ฐ์‚ฐ๊ณผ ์ œ๋„ˆ๋ฆญ ์‚ฌ์šฉ์œผ๋กœ ๋ฐ˜๋ณต ์ค„์ด๊ธฐ

๋งคํ•‘๋œ ํƒ€์ž… ์‚ฌ์šฉํ•˜๊ธฐ

interface State {
  userId: string;
  pageTitle: string;
  recentFiles: string[];
  pageContents: string;
}

interface TopNavState {
  userId: string;
  pageTitle: string;
  recentFiles: string[];
}
  • ์œ„์™€ ๊ฐ™์€ ๊ฒฝ์šฐ๊ฐ€ ์žˆ์„ ๋•Œ ์–ด๋–ป๊ฒŒ ์ค‘๋ณต๋œ ํƒ€์ž…์„ ์ œ๊ฑฐํ• ๊นŒ?
  • ์ฒซ๋ฒˆ์งธ ์•„์ด๋””์–ด๋กœ๋Š” TopNavState ๋ฅผ ํ™•์žฅํ•˜์—ฌ State ๋ฅผ ๋งŒ๋“œ๋Š”๊ฒŒ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๊ฒŒ ์˜ณ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ•์ผ๊นŒ? ์™œ๋ƒํ•˜๋ฉด TopNavState ๋Š” ๊ฒฐ๊ตญ State ์˜ ๋ถ€๋ถ„์ง‘ํ•ฉ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค!
interface TopNavState {
  userId: State[userId];
  pageTitle: State[pageTitle];
  recentFiles: State[RecentFiles];
}
  • ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋˜์ง€ ์•Š์„๊นŒ?
  • ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์€ ๋งคํ•‘๋œ ํƒ€์ž…์„ ์ด์šฉํ•˜๋Š” ๊ฒƒ!
type TopNavState = {
  [k in 'userId' | 'pageTitle' | 'recentFiles']: State[k];
};
  • ์œ„์™€ ๊ฐ™์€ ๋งคํ•‘๋œ ํƒ€์ž…์€ ๋ฐฐ์—ด ํ•„๋“œ๋ฅผ ๋ฃจํ”„ ๋„๋Š”๊ฒƒ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์ด๋‹ค.
  • ์‚ฌ์‹ค ์œ„๋Š” ์•„๋ž˜์˜ ํƒ€์Šค์˜ ์œ ํ‹ธ๋ฆฌํ‹ฐํƒ€์ž…์œผ๋กœ ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•˜๋‹ค.
type TopNavState = Pick<State, 'userId' | 'pageTitle' | 'recentFiles'>;

์ œ๋„ค๋ฆญ ํƒ€์ž…

  • ์ œ๋„ค๋ฆญ ํƒ€์ž…์€.. ํƒ€์ž…์„ ์œ„ํ•œ ํ•จ์ˆ˜๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ์‰ฝ๋‹ค.
  • ๊ทธ๋Ÿฐ๋ฐ..์ œ๋„ค๋ฆญ ํƒ€์ž…์—์„œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ œํ•œ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€..?!
  • ๋ฐ”๋กœ extends ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
  • extends ๋ฅผ ์ด์šฉํ•˜๋ฉด ์ œ๋„ค๋ฆญ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ํŠน์ • ํƒ€์ž…์„ ํ™•์žฅํ•œ๋‹ค๊ณ  ์„ ์–ธํ•˜๋Š” ๊ฒƒ ์ด๋‹ค.
type Pick<T, K> = {
  [k in K]: T[k];
};
// K ํƒ€์ž…์€ 'string | number | symbol ' ํƒ€์ž…์— ํ• ๋‹น ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • K๋Š” T ํƒ€์ž…๊ณผ ๋ฌด๊ด€ํ•˜๊ณ  ๋ฒ”์œ„๊ฐ€ ๋„ˆ๋ฌด ๋„“๋‹ค.
  • K ๋Š” ์ธ๋ฑ์Šค๋กœ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋Š” string | number | symbol ์ด ๋˜์–ด์•ผํ•˜๋ฉฐ, ์‹ค์ œ๋กœ ๋ฒ”์œ„๋ฅผ ๋” ์ขํž ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.
type Pick<T, K extends keyof T> = {
  [k in K]: T[k];
};

๋™์  ๋ฐ์ดํ„ฐ์— ์ธ๋ฑ์Šค ์‹œ๊ทธ๋‹ˆ์ณ ์‚ฌ์šฉํ•˜๊ธฐ

์ธ๋ฑ์Šค ์‹œ๊ทธ๋‹ˆ์ณ์˜ ๋ฌธ์ œ์ 

  1. ์ž˜๋ชป๋œ ํ‚ค๋ฅผ ํฌํ•จํ•ด ๋ชจ๋“  ํ‚ค๋ฅผ ํ—ˆ์šฉํ•œ๋‹ค.
  2. ํŠน์ • ํ‚ค๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค.
  3. ํ‚ค๋งˆ๋‹ค ๋‹ค๋ฅธ ํƒ€์ž…์„ ๊ฐ€์งˆ ์ˆ˜ ์—†๋‹ค.
  4. ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ž๋™์™„์„ฑ ๊ธฐ๋Šฅ์ด ์ง€์›๋˜์ง€ ์•Š๋Š”๋‹ค.

์ธ๋ฑ์Šค ์‹œ๊ทธ๋‹ˆ์ณ๋ฅผ ์‚ฌ์šฉ ํ•ด์•ผ ํ•˜๋Š”๊ฒฝ์šฐ

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

number ์ธ๋ฑ์Šค ์‹œ๊ทธ๋‹ˆ์ณ ๋ณด๋‹ค๋Š” Array, ํŠœํ”Œ, ArrayLike ์‚ฌ์šฉํ•˜๊ธฐ

  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” number ํƒ€์ž…์„ ๊ฐ์ฒด์˜ ํ‚ค๋กœ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ๋ฐฐ์—ด์˜ ๊ฒฝ์šฐ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœโ€ฆ ํ‚ค๋Š” ๋ฌด์กฐ๊ฑด ๋ฌธ์ž์—ด์ด๋‹ค.
  • ํ•˜์ง€๋งŒ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” ์ˆซ์ž ํ‚ค๋ฅผ ํ—ˆ์šฉํ•˜๊ณ  ๋ฌธ์ž์—ด ํ‚ค์™€ ๋‹ค๋ฅธ ๊ฒƒ์œผ๋กœ ์ด์šฉํ•˜๋„๋ก ๊ตฌํ˜„๋˜์–ด ์žˆ๋‹ค.
interface Array<T> {
  // ...
  [n: number]: T;
}

์ด๋ ‡๊ฒŒ ๋ง์ด๋‹ค.

  • ํ•˜์ง€๋งŒ ๋Ÿฐํƒ€์ž„์—๋Š” ์—ํฌ๋งˆ์Šคํฌ๋ฆฝํŠธ ํ‘œ์ค€์ด ์„œ์ˆ ํ•˜๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ ๋ฌธ์ž์—ด ํ‚ค๋กœ ์ธ์‹ํ•˜๋ฏ€๋กœ, ์ด ์ฝ”๋“œ๋Š” ์™„์ „ํžˆ ๊ฐ€์ƒ์˜ ์ฝ”๋“œ๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํƒ€์ž…์ฒดํฌ ์‹œ์ ์— ์˜ค๋ฅ˜๋ฅผ ์žก์„ ์ˆ˜ ์žˆ์–ด์„œ ์œ ์šฉํ•˜๋‹ค.
  • ์ธ๋ฑ์Šค ์‹œ๊ทธ๋‹ˆ์ณ๊ฐ€ number ๋กœ ํ‘œ๊ธฐ๋˜์–ด์žˆ๋‹ค๋ฉด ์ž…๋ ฅํ•œ ๊ฐ’์ด number ์—ฌ์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜์ง€๋งŒ, ์‹ค์ œ ๋Ÿฐํƒ€์ž„์— ์‚ฌ์šฉ๋˜๋Š” key ์˜ ํƒ€์ž…์€ string ์ด ๋œ๋‹คโ€ฆ!!
  • ๋”ฐ๋ผ์„œ ์™ ๋งŒํ•˜๋ฉด number ์ธ๋ฑ์Šค ์‹œ๊ทธ๋‹ˆ์ณ๋Š” ์‚ฌ์šฉํ•˜์ง€ ๋ง์ž.

ArrayLike

interface ArrayLike<T> {
  readonly length: number;
  readonly [n: number]: T;
}
  • ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ (push, concat) ๊ณผ ๊ฐ™์€ ํƒ€์ž…์€ ์ •์˜๋˜์–ด ์žˆ์ง€ ์•Š์•„์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.
  • ํŠœํ”Œ ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ธ๋ฑ์Šค๋กœ์˜ ์ ‘๊ทผ๊ณผ length ์ ‘๊ทผ๋งŒ ํ—ˆ์šฉํ•œ๋‹ค.

๋ณ€๊ฒฝ ๊ด€๋ จ๋œ ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด readonly ์‚ฌ์šฉํ•˜๊ธฐ

Readonly ๋ฐฐ์—ด์˜ ํŠน์ง•

  • ๋ฐฐ์—ด์˜ ์š”์†Œ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ์“ธ ์ˆ˜๋Š” ์—†๋‹ค.

  • length๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ฐ”๊ฟ€ ์ˆ˜ ์—†๋‹ค.

  • ๋ฐฐ์—ด์„ ๋ณ€๊ฒฝํ•˜๋Š” pop์„ ๋น„๋กฏํ•œ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœ ํ•  ์ˆ˜ ์—†๋‹ค.

  • number[] ๋Š” readonly number[] ๋ณด๋‹ค ๊ธฐ๋Šฅ์ด ๋งŽ๊ธฐ ๋•Œ๋ฌธ์—, readonly number[] ์˜ ์„œ๋ธŒํƒ€์ž…์ด ๋œ๋‹ค.

  • ๋”ฐ๋ผ์„œ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๋ฐฐ์—ด์„ readonly ๋ฐฐ์—ด์— ํ• ๋‹น ๊ฐ€๋Šฅํ•˜๋‹ค. (ํ•˜์ง€๋งŒ ๊ทธ ๋ฐ˜๋Œ€๋Š” ๋ถˆ๊ฐ€๋Šฅ!)

์–•๊ฒŒ (shallow) ๋™์ž‘ํ•˜๋Š” readonly

readonly string[][]; // 1๋ฒˆ

(readonly string[])[]; //2๋ฒˆ
  • 1๋ฒˆ : ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๋ฐฐ์—ด์˜ readonly ๋ฐฐ์—ด

  • 2๋ฒˆ : readonly ๋ฐฐ์—ด์˜ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๋ฐฐ์—ด

  • Readonly ์ œ๋„ค๋ฆญ๋„ ์–•๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.

const ์™€ readonly ์˜ ์ฐจ์ด

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

์ถ”๋ก  ๊ฐ€๋Šฅํ•œ ํƒ€์ž…์„ ์‚ฌ์šฉํ•ด ์žฅํ™ฉํ•œ ์ฝ”๋“œ ๋ฐฉ์ง€ํ•˜๊ธฐ

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” ํƒ€์ž…์ถ”๋ก ์„ ์ž˜ ํ•ด์ค€๋‹ค. ํ•˜์ง€๋งŒ ํƒ€์ž… ์ถ”๋ก ์„ ์ž˜ํ•ด์คŒ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , ๋ช…์‹œ์ ์œผ๋กœ ํƒ€์ž…ํ•‘์„ ํ•ด์•ผํ•  ๋•Œ๋Š” ์–ธ์ œ์ผ๊นŒ?

1. ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด์„ ์ •์˜ํ•  ๋–„

why

  • ์ž‰์—ฌ ์†์„ฑ ์ฒดํฌ๋ฅผ ํ•ด์ค€๋‹ค.
  • ๋ณ€์ˆ˜๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ์ˆœ๊ฐ„์ด ์•„๋‹Œ, ํ• ๋‹นํ•˜๋Š” ์‹œ์ ์— ์˜ค๋ฅ˜๊ฐ€ ํ‘œ์‹œ๋˜๋„๋ก ํ•ด์ค€๋‹ค.

2. ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜๊ฐ’์„ ์ •์˜ ํ•  ๋•Œ

why

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

๋‹ค๋ฅธ ํƒ€์ž…์—๋Š” ๋‹ค๋ฅธ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ

why?

  1. ์„œ๋กœ ๊ด€๋ จ์ด ์—†๋Š” ๋‘ ๊ฐœ์˜ ๊ฐ’์„ ๋ถ„๋ฆฌํ•œ๋‹ค.
  2. ๋ณ€์ˆ˜๋ช…์„ ๋” ๊ตฌ์ฒด์ ์œผ๋กœ ์ง€์„ ์ˆ˜ ์žˆ๋‹ค.
  3. ํƒ€์ž… ์ถ”๋ก ์„ ํ–ฅ์ƒ์‹œํ‚ค๋ฉฐ, ํƒ€์ž… ๊ตฌ๋ฌธ์ด ๋ถˆํ•„์š”ํ•ด์ง„๋‹ค.
  4. ํƒ€์ž…์ด ์ข€ ๋” ๊ฐ„๊ฒฐํ•ด์ง„๋‹ค.
  5. let ๋Œ€์‹  const ๋กœ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํƒ€์ž…์ด ๋ฐ”๋€Œ๋Š” ๋ณ€์ˆ˜๋Š” ๋˜๋„๋ก ํ”ผํ•ด์•ผ ํ•˜๋ฉฐ, ๋ชฉ์ ์ด ๋‹ค๋ฅธ ๊ณณ์—๋Š” ๋ณ„๋„์˜ ๋ณ€์ˆ˜๋ช…์„ ์‚ฌ์šฉํ•˜์ž.

ํƒ€์ž… ๋„“ํžˆ๊ธฐ

  • ๋Ÿฐํƒ€์ž„์— ๋ชจ๋“  ๋ณ€์ˆ˜๋Š” ์œ ์ผํ•œ ๊ฐ’์„ ๊ฐ€์ง„๋‹ค.
  • ํ•˜์ง€๋งŒ, ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ž‘์„ฑ๋œ ์ฝ”๋“œ๋ฅผ ์ฒดํฌํ•˜๋Š” ์ •์  ๋ถ„์„ ์‹œ์ ์— ๋ณ€์ˆ˜๋Š” (๋Ÿฐํƒ€์ž„ ์‹œ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ) ๊ฐ€๋Šฅ ํ•œ ๊ฐ’๋“ค์˜ ์ง‘ํ•ฉ์ธ ํƒ€์ž…์„ ๊ฐ€์ง„๋‹ค.
  • ์ƒ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ณ€์ˆ˜๋ฅผ ์ดˆ๊ธฐํ™” ํ•  ๋•Œ, ํƒ€์ž…์„ ๋ช…์‹œํ•˜์ง€ ์•Š์œผ๋ฉด ํƒ€์ž… ์ฒด์ปค๋Š” ํƒ€์ž…์„ ๊ฒฐ์ •ํ•ด์•ผ ํ•œ๋‹ค.
  • ์ฆ‰, ์ง€์ •๋œ ๋‹จ์ผ ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ํ• ๋‹น ๊ฐ€๋Šฅํ•œ ๊ฐ’๋“ค์˜ ์ง‘ํ•ฉ์„ ์œ ์ถ”ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๋œป์ด๋‹ค. => ๋„“ํžˆ๊ธฐ(widening)
interface Vector3 {
  x: number;
  y: number;
  z: number;
}
function getComponent(vector: Vector3, axis: 'x' | 'y' | 'z') {
  return vector[axis];
}

let x = 'x';
let vec = { x: 10, y: 20, z: 30 };
getComponent(vec, x);
// ๋Ÿฐํƒ€์ž„์‹œ ๋™์ž‘์€ ์ž˜ ๋˜๋Š”๋ฐ ํŽธ์ง‘๊ธฐ์—์„œ ์•„๋ž˜์™€ ๊ฐ™์€ ์˜ค๋ฅ˜ ๋‚˜์˜ด
// ~ 'string' ํ˜•์‹์˜ ์ธ์ˆ˜๋Š” "x" | "y" | "z" ํ˜•์‹์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์— ํ• ๋‹น๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • getComponent ํ•จ์ˆ˜๋Š” ๋‘๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜์— โ€œxโ€ | โ€œyโ€ | โ€œzโ€ ํƒ€์ž…์„ ๊ธฐ๋Œ€ํ–ˆ์ง€๋งŒ x ์˜ ํƒ€์ž…์€ ํ• ๋‹น ์‹œ์ ์— ๋„“ํžˆ๊ธฐ๊ฐ€ ๋™์ž‘ํ•ด์„œ string ์œผ๋กœ ์ถ”๋ก ๋˜์—ˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ string ํƒ€์ž…์€ โ€œxโ€ | โ€œyโ€ | โ€œzโ€ ํƒ€์ž…์— ํ• ๋‹น์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ ์˜ค๋ฅ˜๊ฐ€ ๋‚œ๋‹ค.

๋„“ํžˆ๊ธฐ์˜ ๊ณผ์ • ์ œ์–ดํ•˜๊ธฐ

  • const ์‚ฌ์šฉํ•˜๊ธฐ. (let ๋Œ€์‹  const ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋” ์ข์€ ํƒ€์ž…์ด ๋œ๋‹ค.)
  • ํ•˜์ง€๋งŒ const ์—ญ์‹œ ์ฐธ์กฐํ˜•์˜ ๊ฒฝ์šฐ ..ํŠนํžˆ ๋ฐฐ์—ด์˜ ๊ฒฝ์šฐ ๋ฐฐ์—ด์— ํŠœํ”Œ ํƒ€์ž…์„ ์ถ”๋ก ํ•ด์•ผ ํ• ์ง€, ์š”์†Œ๋“ค์€ ์–ด๋–ค ํƒ€์ž…์„ ์ถ”๋ก ํ• ์ง€ ์•Œ์ˆ˜์—†๋‹ค. ๊ฐ์ฒด๋„ ๋งˆ๊ฐ€์ง€.
  • ๊ฐ์ฒด์˜ ๊ฒฝ์šฐ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์˜ ๋„“ํžˆ๊ธฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๊ฐ ์š”์†Œ๋ฅผ let ์œผ๋กœ ํ• ๋‹น ๋œ ๊ฒƒ ์ฒ˜๋Ÿผ ๋‹ค๋ฃฌ๋‹ค.

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์˜ ๊ธฐ๋ณธ ๋™์ž‘(์ถ”๋ก )์„ ์žฌ์ •์˜ ํ•˜๊ธฐ

  1. ๋ช…์‹œ์  ํƒ€์ž… ๊ตฌ๋ฌธ ์ œ๊ณตํ•˜๊ธฐ
  2. ํƒ€์ž… ์ฒด์ปค์— ์ถ”๊ฐ€์ ์ธ ๋ฌธ๋งฅ์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ. (ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๊ฐ’์„ ์ „๋‹ฌํ•˜๊ธฐ.)
  3. const ๋‹จ์–ธ๋ฌธ ์‚ฌ์šฉํ•˜๊ธฐ.
const v2 = {
  x: 1 as const,
  y: 2,
};
// ํƒ€์ž…์€ { x: 1 ; y: number; }

const v3 = {
  x: 1,
  y: 2,
} as const;

// ํƒ€์ž…์€ { readonly x:1, readonly y:2 };

ํƒ€์ž… ์ขํžˆ๊ธฐ

  • ํƒ€์ž… ๋„“ํžˆ๊ธฐ์˜ ๋ฐ˜๋Œ€
  • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋„“์€ ํƒ€์ž…์œผ๋กœ๋ถ€ํ„ฐ ์ข์€ ํƒ€์ž…์œผ๋กœ ์ง„ํ–‰ํ•˜๋Š” ๊ณผ์ •
const el = document.getElementById('foo');
if (el) {
  el;
  el.innerHTML = ' wow '.blikc();
} else {
  el;
  alert('No Element');
}
  • ๋งŒ์•ฝ el ์ด null ์ด๋ฉด ๋ถ„๊ธฐ๋ฌธ์˜ ์ฒซ ๋ฒˆ์งธ ๋ธ”๋ก์ด ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค. ์ฆ‰, ์ฒซ๋ฒˆ์งธ ๋ธ”๋ก์—์„œ HTMLElement | null ํƒ€์ž…์˜ null ํƒ€์ž…์„ ์ œ์™ธํ•˜๋ฏ€๋กœ ๋” ์ข์€ ํƒ€์ž…์ด ๋˜์–ด ์ž‘์—…์ด ํ›จ์”ฌ ์‰ฌ์›Œ์ง„๋‹ค.
  • ํƒ€์ž… ์ฒด์ปค๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์ด๋Ÿฌํ•œ ์กฐ๊ฑด๋ฌธ์—์„œ ํƒ€์ž… ์ขํžˆ๊ธฐ๋ฅผ ์ž˜ํ•ด๋‚ด์ง€๋งŒ, ํƒ€์ž… ๋ณ„์นญ์ด ์กด์žฌํ•œ๋‹ค๋ฉด ๊ทธ๋Ÿฌ์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค. -> ์™œ์ผ๊นŒ?! ํƒ€์ž…๋ณ„์นญ์— ๋Œ€ํ•œ๊ฑด ๋‚˜์ค‘์— ๋‹ค๋ฃฌ๋‹ค.

ํƒ€์ž… ์ขํžˆ๋Š” ๋ฐฉ๋ฒ•

  1. ๋ถ„๊ธฐ๋ฌธ์—์„œ ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๊ฑฐ๋‚˜ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ ๋ธ”๋ก์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์—์„œ ๋ณ€์ˆ˜์˜ ํƒ€์ž…์„ ์ขํž ์ˆ˜๋„ ์žˆ๋‹ค.
  2. instanceof ๋ฅผ ํ†ตํ•ด์„œ ํƒ€์ž…์„ ์ขํžŒ๋‹ค. (๋ถ„๊ธฐ๋ฌธ)
  3. ์†์„ฑ ์ฒดํฌ๋กœ ํƒ€์ž… ์ฒดํฌํ•œ๋‹ค. a in ab
  4. Array.isArray ๊ฐ™์€ ๋‚ด์žฅํ•จ์ˆ˜๋กœ ํƒ€์ž… ์ขํžŒ๋‹ค.
  5. ํƒœ๊ทธ ๋ถ™์—ฌ์„œ โ€˜ํƒœ๊ทธ๋œ ์œ ๋‹ˆ์˜จ or ๊ตฌ๋ณ„๋œ ์œ ๋‹ˆ์˜จ or ์„œ๋กœ์†Œ ์œ ๋‹ˆ์˜จโ€™ ๋งŒ๋“ค๊ธฐ
  • ์„œ๋กœ์†Œ ์œ ๋‹ˆ์˜จ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋ฉด, ์„œ๋กœ ๊ฒน์น˜์ง€ ์•Š๋Š” ์—ฌ๋Ÿฌ ๊ฒฝ์šฐ ์ค‘ ํ•˜๋‚˜์ธ ํƒ€์ž…์„ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์–ธ์ œ ์œ ์šฉํ• ๊นŒ..??
๋„คํŠธ์›Œํฌ ์š”์ฒญ: ์š”์ฒญ์€ ์„ฑ๊ณตํ•˜๊ฑฐ๋‚˜ ์‹คํŒจํ•˜๊ฒ ์ง€๋งŒ, ์„ฑ๊ณตํ•œ ๋™์‹œ์— ์‹คํŒจํ•  ์ˆ˜๋Š” ์—†๋‹ค.
๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ํŠน์ • ์•„์ด๋””๋ฅผ ๊ฐ–๋Š” ์ปฌ๋Ÿผ์„ ์ฟผ๋ฆฌ: ํ•ด๋‹น ์ปฌ๋Ÿผ์ด ์žˆ๊ฑฐ๋‚˜ ์—†์ง€๋งŒ, ์žˆ์œผ๋ฉด์„œ ์—†์„ ์ˆ˜๋Š” ์—†๋‹ค.
์–ด๋–ค ํŒŒ์ผ๋ช…์„ ๊ฐ–๋Š” ํŒŒ์ผ ๋‚ด์šฉ์„ ์ฝ์–ด์˜ค๋Š” ๊ฒฝ์šฐ: ํ•ด๋‹น ํŒŒ์ผ์ด ์žˆ๊ฑฐ๋‚˜ ์—†์ง€๋งŒ, ์žˆ์œผ๋ฉด์„œ ์—†์„ ์ˆ˜๋Š” ์—†๋‹ค.
  • ์„œ๋กœ์†Œ ์œ ๋‹ˆ์˜จ ํƒ€์ž…์—์„œ๋Š” ์„œ๋กœ ๊ฒน์น˜๋Š”๊ฒŒ ์—†๋‹ค. ๋”ฐ๋ผ์„œ switch ๋ฌธ์„ ์‚ฌ์šฉํ•ด์„œ ํŠน์ • ํƒ€์ž…์ด๋ฉด ~ ์–ด๋–ค ๋™์ž‘์„ ํ•˜๋„๋ก ์œ ๋„ํ•  ์ˆ˜ ์žˆ๋‹ค. https://ahnheejong.gitbook.io/ts-for-jsdev/06-type-system-deepdive/disjoint-union-type
// ์‚ฌ์šฉ์ž ์ •์˜ ํƒ€์ž…๊ฐ€๋“œ!

function isInputElement (el: HTMLElement): el is HTMLInputElement {
    return 'value' in el;
}

function getElementContent(el: HTMLElement){
     if(isInputElement(el){
          return el.value;
     }
}
function isDefined<T>(x: T | undefined): x is T {
  return x !== undefined;
}
  • ์ฃผ์˜ํ•ด์•ผํ• ๊ฒƒโ€ฆ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ typeof null === 'object'

ํ•œ๊บผ๋ฒˆ์— ๊ฐ์ฒด ์ƒ์„ฑํ•˜๊ธฐ

  • ์†์„ฑ์„ ๊ฐ์ฒด์— ๊ฐ๊ฐ ์ถ”๊ฐ€ํ•˜์ง€ ๋ง๊ณ  ํ•œ๊บผ๋ฒˆ์— ๊ฐ์ฒด๋กœ ๋งŒ๋“ค์–ด์•ผ ํƒ€์ž…์ถ”๋ก ์ด ์ž˜๋œ๋‹ค.

์กฐ๊ฑด๋ถ€๋กœ ๊ฐ์ฒด์— ์†์„ฑ ์ถ”๊ฐ€ํ•˜๊ธฐ

function addOptional<T extends object, U extends object>(a: T, b: U | null): T & Partial<U> {
  return { ...a, ...b };
}

const pharaoh = addOptional(nameTItle, hasDates ? { start: -2589, end: -2566 } : null);

์ผ๊ด€์„ฑ ์žˆ๋Š” ๋ณ„์นญ ์‚ฌ์šฉํ•˜๊ธฐ

  • ๋ณ„์นญ..?! ์•„๋ž˜์™€ ๊ฐ™์€ ์˜ˆ์‹œ!
const state = { location: 1 };
const loc = state.location; // ์š”๊ฒŒ ๋ณ„์นญ!
  • ๋ณ„์นญ์„ ์‚ฌ์šฉํ•˜๋ฉด ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๊ฐ€ ํƒ€์ž…์„ ์ขํžˆ๋Š” ๊ฒƒ์„ ๋ฐฉํ•ดํ•œ๋‹ค
  • ๋ณ„์นญ์˜ ๊ฐ’์„ ๋ฐ”๊พธ๋ฉด ์›๋ณธ ๊ฐ์ฒด์˜ ๊ฐ’๋„ ๋ณ€๊ฒฝ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋น„๋™๊ธฐ ์ฝ”๋“œ์—๋Š” ์ฝœ๋ฐฑ ๋Œ€์‹  async ํ•จ์ˆ˜ ์‚ฌ์šฉํ•˜๊ธฐ

์ฝœ๋ฐฑ๋ณด๋‹ค๋Š” ํ”„๋กœ๋ฏธ์Šค ์‚ฌ์šฉํ•˜๊ธฐ

  • ์ฝœ๋ฐฑ๋ณด๋‹ค ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์‰ฝ๋‹ค.
  • ์ฝœ๋ฐฑ๋ณด๋‹ค ํ”„๋กœ๋ฏธ์Šค๊ฐ€ ํƒ€์ž… ์ถ”๋ก ์ด ์‰ฝ๋‹ค.
  • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์ž˜ ์ถ”๋ก ํ•œ๋‹ค!

ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ๋ณด๋‹ค async/await ์ƒ์„ฑํ•˜๊ธฐ

  • ์ผ๋ฐ˜์ ์œผ๋กœ ๋” ๊ฐ„๊ฒฐํ•˜๊ณ  ์ง๊ด€์ ์ธ ์ฝ”๋“œ๊ฐ€ ๋œ๋‹ค.
  • async ํ•จ์ˆ˜๋Š” ํ•ญ์ƒ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๊ฐ•์ œํ•œ๋‹ค.
  • async ํ•จ์ˆ˜์—์„œ ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด, ๋˜ ๋‹ค๋ฅธ ํ”„๋กœ๋ฏธ์Šค๋กœ ๋ž˜ํ•‘๋˜์ง€ ์•Š๋Š”๋‹ค. ์ฆ‰ ๋ฐ˜ํ™˜ํƒ€์ž…์ด Promise<Promise<T>> ๊ฐ€ ์•„๋‹ˆ๋ผ, Promise<T> ๊ฐ€ ๋œ๋‹ค.

ํƒ€์ž… ์ถ”๋ก ์— ๋ฌธ๋งฅ์ด ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ๋˜๋Š”์ง€ ์ดํ•ดํ•˜๊ธฐ

  • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” ํƒ€์ž…์„ ์ถ”๋ก ํ•  ๋•Œ, ๋‹จ์ˆœํžˆ ๊ฐ’๋งŒ ๊ณ ๋ คํ•˜์ง€ ์•Š๋Š”๋‹ค! ๊ฐ’์ด ์กด์žฌํ•˜๋Š” ๊ณณ์˜ ๋ฌธ๋งฅ๊นŒ์ง€ ์‚ดํ•€๋‹ค.
type Language = 'JavaScript' | 'TypeScript';

function setLanguage(language: Language) {}

setLanguage('JavaScript'); // ์ •์ƒ

let language = 'JavaScript';
setLanguage(language); // Error
// 'string' ํ˜•์‹์˜ ์ธ์ˆ˜๋Š” 'Language' ํ˜•์‹์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์— ํ• ๋‹น ๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • why?
  • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” ํ• ๋‹น ์‹œ์ ์— ํƒ€์ž…์„ ์ถ”๋ก ํ•œ๋‹ค.
  • ๋”ฐ๋ผ์„œ string ์œผ๋กœ ์ถ”๋ก ๋œ๊ฒƒโ€ฆ

ํ•ด๊ฒฐ๋ฐฉ๋ฒ•

  1. ํƒ€์ž…์„ ์–ธํ•˜๊ธฐ
let language: Language = 'JavaScript';
  1. ์ƒ์ˆ˜๋กœ ๋งŒ๋“ค๊ธฐ
const language = 'JavaScript';
  • ํƒ€์ž…์ฒด์ปค์—๊ฒŒ language ๋ณ€์ˆ˜๋Š” ๋ณ€ํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ์•Œ๋ ค์ค˜์„œ ํƒ€์ž…์„ ์ขํžŒ๋‹ค.

ํŠœํ”Œ ์‚ฌ์šฉ


function panTo(where:[number,number]){}

panTo([10,20]); // ์ •์ƒ

conset loc = [10,20];
panTo(loc);
// number[] ํ˜•์‹์˜ ์ธ์ˆ˜๋Š”
// [number,number] ํ˜•์‹์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์— ํ• ๋‹น๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • const ๋„ ์•ˆ๋จนํžŒ๋‹ค. ์™œ? ๋‹น์—ฐํžˆ ์ฐธ์กฐํƒ€์ž…์ด๊ธฐ ๋•Œ๋ฌธ์—!

ํ•ด๊ฒฐํ•˜๊ธฐ as const

function panTo(where: [number, number]) {}

const loc = [10, 20] as const;
panTo(loc);
// Error: readonly[10,20] ํ˜•์‹์€
// ๋ณ€๊ฒฝ๊ฐ€๋Šฅํ•œ ํ˜•์‹ [number,number] ์— ํ• ๋‹น ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • panTo ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ€์ž…์„ readonly ๋กœ ๋ฐ”๊ฟ”์•ผํ•จ.
  • as const ๋Š” ์œ„์™€๊ฐ™์ด ๋ฌธ๋งฅ ์†์‹ค๊ณผ ๊ด€๋ จ๋œ ๋ฌธ์ œ๋ฅผ ๊น”๋”ํ•˜๊ฒŒ ํ•ด๊ฒฐํ•˜์ง€๋งŒ, ๋‹จ์ ์ด์žˆ์Œ.
  • ํƒ€์ž… ์ •์˜์— ์‹ค์ˆ˜๊ฐ€ ์žˆ๋‹ค๋ฉด ์˜ค๋ฅ˜๋Š” ํƒ€์ž… ์ •์˜๊ฐ€ ์•„๋‹ˆ๋ผ ํ˜ธ์ถœ๋˜๋Š” ๊ณณ์—์„œ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๊ฒƒ.

์œ ํšจํ•œ ์ƒํƒœ๋งŒ ํ‘œํ˜„ํ•˜๋Š” ํƒ€์ž…์„ ์ง€ํ–ฅํ•˜๊ธฐ

interface State {
  pageText: string;
  isLoading: boolean;
  error?: string;
}

์œ„์™€ ๊ฐ™์€ ํƒ€์ž…์ด ์žˆ๋‹ค๋ฉด..

  • isLoading ์ด true ์ด๊ณ  ๋™์‹œ์— error ๊ฐ’์ด ์กด์žฌํ•˜๋Š” ์ƒํƒœ..๋ฅผ ์šฐ๋ฆฌ๋Š” ์œ„์˜ ํƒ€์ž…์œผ๋กœ ์•Œ ์ˆ˜ ์—†๋‹ค.
  • ์ฆ‰ ์œ„์˜ ํƒ€์ž…์€ isLoading ์ด true ์ด๋ฉด์„œ error ๊ฐ’์ด ์„ค์ •๋˜๋Š” ๋ฌดํšจํ•œ ์ƒํƒœ๋ฅผ ํ—ˆ์šฉํ•ด๋ฒ„๋ฆฐ๋‹ค!
interface RequestPending {
  state: 'pending';
}

interface RequestError {
  state: 'error';
  error: string;
}

interface RequestSuccess {
  state: 'ok';
  pageText: string;
}

type RequestState = RequestPending | RequestError | RequestSuccess;

interface State {
  currentPage: string;
  requests: { [page: string]: RequestState };
}

์‚ฌ์šฉํ•  ๋•Œ๋Š” ๋„ˆ๊ทธ๋Ÿฝ๊ฒŒ, ์ƒ์„ฑํ•  ๋•Œ๋Š” ์—„๊ฒฉํ•˜๊ฒŒ

  • ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ€์ž…์€ ํƒ€์ž…์˜ ๋ฒ”์œ„๊ฐ€ ๋„“์–ด๋„ ๋œ๋‹ค. (์‚ฌ์šฉ ์‹œ)
  • ๋ฐ˜ํ™˜๋˜๋Š” ๊ฒฐ๊ณผ์˜ ํƒ€์ž…์€ ๋ฒ”์œ„๊ฐ€ ๋” ๊ตฌ์ฒด์ ์ด์–ด์•ผ ํ•œ๋‹ค. (์ƒ์„ฑ ์‹œ)

๋ฌธ์„œ์— ํƒ€์ž… ์ •๋ณด๋ฅผ ์“ฐ์ง€ ์•Š๊ธฐ

  • ์ฃผ์„๊ณผ ๋ณ€์ˆ˜๋ช…์— ํƒ€์ž… ์ •๋ณด๋ช…์„ ์ ๋Š” ๊ฒƒ์€ ํ”ผํ•˜๊ธฐ.

ํƒ€์ž… ์ฃผ๋ณ€์— null ๊ฐ’ ๋ฐฐ์น˜ํ•˜๊ธฐ

  • B ๋ณ€์ˆ˜๊ฐ€ A ๋ณ€์ˆ˜์˜ ๊ฐ’์œผ๋กœ๋ถ€ํ„ฐ ๋น„๋กฏ๋˜๋Š” ๊ฐ’์ด๋ผ๋ฉด, A ๊ฐ€ null ์ด ๋  ์ˆ˜ ์—†์„๋•Œ B ์—ญ์‹œ null ์ด ๋  ์ˆ˜ ์—†๊ณ , ๊ทธ ๋ฐ˜๋Œ€๋กœ A ๊ฐ€ null ์ด ๋  ์ˆ˜ ์žˆ๋‹ค๋ฉด B ์—ญ์‹œ null ์ด ๋  ์ˆ˜ ์žˆ๋‹ค.
  • ๊ฐ’์ด ์ „๋ถ€ null ์ด๊ฑฐ๋‚˜ ์ „๋ถ€ null ์ด ์•„๋‹Œ ๊ฒฝ์šฐ๋กœ ๋ถ„๋ช…ํžˆ ๊ตฌ๋ถ„๋œ๋‹ค๋ฉด, ๊ฐ’์ด ์„ž์—ฌ ์žˆ์„ ๋•Œ ๋ณด๋‹ค ๋‹ค๋ฃจ๊ธฐ ์‰ฝ๋‹ค.
  • ํƒ€์ž…์— null ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ๋ฅผ ๋ชจ๋ธ๋ง ํ•  ์ˆ˜ ์žˆ๋‹ค.
function extent(nums: number[]) {
  let min, max;
  for (const num of nums) {
    if (!min) {
      min = num;
      max = num;
    } else {
      min = Math.min(min, num);
      max = Math.max(max, num);
      // 'number' | 'undefined' ํ˜•์‹์˜ ์ธ์ˆ˜๋Š” 'number' ํ˜•์‹์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์— ํ• ๋‹น ๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
    }
  }
  return [min, max];
}
  • nums ๋ฐฐ์—ด์ด 0 ์œผ๋กœ ์‹œ์ž‘ํ•˜๋ฉด..์ œ๋Œ€๋กœ ๋œ ๋™์ž‘์ด ์•ˆ๋œ๋‹ค. (0์ด Nullish ํ•˜๋ฏ€๋กœ)
  • nums ๋ฐฐ์—ด์ด ๋น„์–ด์žˆ๋‹ค๋ฉด ํ•จ์ˆ˜๋Š” [undefined,undefined] ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • ์œ„์—์„œ undefined ๋ฅผ min ์—์„œ๋งŒ ์ œ์™ธํ–ˆ๊ณ , max ๋Š” ์ œ์™ธํ•˜์ง€ ์•Š์•„์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๊ทธ๋ ‡๋‹ค๊ณ  max ์— ๋Œ€ํ•œ ์ฒดํฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉดโ€ฆ๋ฒ„๊ทธ๊ฐ€ ๋˜ ๋ฐœ์ƒํ•œ๋‹ค!!
  • ๋” ๋‚˜์€ ํ•ด๋ฒ•์„ ์ฐพ์•„๋ณด๊ธฐ
function extent(nums: number[]) {
  let result: [number, number] | null = null;
  for (const num of nums) {
    if (!result) {
      result = [num, num];
    } else {
      result = [Math.min(result[0], num), Math.max(result[1], num)];
    }
  }
  return result;
}
  • extent ์˜ ๊ฒฐ๊ด๊ฐ’์œผ๋กœ ๋‹จ์ผ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ์„ค๊ณ„ ๊ฐœ์„ 

  • ๋”ฐ๋ผ์„œ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๊ฐ€ null ๊ฐ’ ์‚ฌ์ด์˜ ๊ด€๊ณ„ (min์ด null ์ด๋ฉด max ๋„ null , vice versa)๋ฅผ ์•ˆ๋‹ค.

  • ์ฆ‰ ํ•œ ๊ฐ’์˜ null ์—ฌ๋ถ€๊ฐ€ ๋‹ค๋ฅธ ๊ฐ’์˜ null ์—ฌ๋ถ€์— ์•”์‹œ์ ์œผ๋กœ ๊ด€๋ จ๋˜๋„๋ก ์„ค๊ณ„ํ•˜์ง€ ๋ง๊ธฐ

  • API ์ž‘์„ฑ ์‹œ์—๋Š” ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ํฐ ๊ฐ์ฒด๋กœ ๋งŒ๋“ค๊ณ  ๋ฐ˜ํ™˜ ํƒ€์ž… ์ „์ฒด๊ฐ€ null ์ด๊ฑฐ๋‚˜ null ์ด ์•„๋‹ˆ๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.

  • ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ๋Š”, ํ•„์š”ํ•œ ๋ชจ๋“  ๊ฐ’์ด ์ค€๋น„ ๋˜์—ˆ์„ ๋•Œ ์ƒ์„ฑํ•˜์—ฌ null ์ด ์กด์žฌํ•˜์ง€ ์•Š๋„๋ก ํ•˜์ž.

์œ ๋‹ˆ์˜จ์˜ ์ธํ„ฐํŽ˜์ด์Šค ๋ณด๋‹ค๋Š” ์ธํ„ฐํŽ˜์ด์Šค์˜ ์œ ๋‹ˆ์˜จ ์‚ฌ์šฉํ•˜๊ธฐ

interface Layer {
  layout: FillLayout | LineLayout | PointLayout;
  paint: FillPaint | LinePaint | PointPaint;
}
  • ์œ„์˜ ํƒ€์ž…์˜ ๊ฒฝ์šฐ..
  • layout ์ด FillLayout ์ด๋ฉด์„œ paint ๊ฐ€ LinePaint ์ธ๊ฑด ๋ง์ด ๋˜์ง€ ์•Š๋Š”๋ฐ ์ด๋Ÿฌํ•œ ์กฐํ•ฉ์„ ํ—ˆ์šฉํ•˜๊ฒŒ ๋œ๋‹ค!
  • ์•„๋ž˜์™€ ๊ฐ™์ด ํƒ€์ž… ๊ณ„์ธต์„ ๋ถ„๋ฆฌํ•˜์ž. ์„œ๋กœ์†Œ ์œ ๋‹ˆ์˜จ ํƒ€์ž…์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
interface FillLayer {
  layout: FillLayout;
  paint: FillPaint;
}

interface LineLayer {
  layout: LineLayout;
  paint: LinePaint;
}

interface PointLayer {
  layout: PointLayout;
  paint: PointPaint;
}

type Layer = FillLayer | LineLayer | PointLayer;
  • ๋” ๋‚˜์•„๊ฐ€์„œ ํƒœ๊ทธ๋œ ์œ ๋‹ˆ์˜จ ํƒ€์ž…์œผ๋กœ ๋ฆฌํŒฉํ„ฐ๋งํ•˜์ž
interface FillLayer {
  type: 'fill';
  layout: FillLayout;
  paint: FillPaint;
}

interface LineLayer {
  type: 'line';
  layout: LineLayout;
  paint: LinePaint;
}

interface PointLayer {
  type: 'point';
  layout: PointLayout;
  paint: PointPaint;
}

type Layer = FillLayer | LineLayer | PointLayer;
  • ํƒœ๊ทธ๋œ ์œ ๋‹ˆ์˜จ.. ํƒœ๊ทธ๋ž€? ๋Ÿฐํƒ€์ž„์— ์–ด๋–ค ํƒ€์ž…์˜ Layer ๊ฐ€ ์‚ฌ์šฉ๋˜๋Š”์ง€ ํŒ๋‹จํ•˜๋Š”๋ฐ ์“ฐ์ธ๋‹ค.
  • ์œ„์˜ ์˜ˆ์‹œ์—์„œ ํƒœ๊ทธ๋Š” type ์ด ๋œ๋‹ค!

์˜ˆ์‹œ 2

interface Person {
  name: string;
  placeOfBirth?: string;
  dateOfBirth?: number;
}
  • placeOfBirth ์†์„ฑ๊ณผ dateOfBirth ์†์„ฑ์ด ๋‘˜ ๋‹ค ๋™์‹œ์— ์žˆ๊ฑฐ๋‚˜ ์—†์–ด์•ผ ํ•˜๋Š”๋ฐ, ํ•˜๋‚˜๋งŒ ์กด์žฌํ•˜๋Š” ์กฐํ•ฉ์ด ์ƒ์„ฑ ๊ฐ€๋Šฅํ•˜๋‹ค
interface Person {
  name: string;
  birth?: {
    place: string;
    date: number;
  };
}
  • ์œ„์ฒ˜๋Ÿผ ๋‘๊ฐœ์˜ ์†์„ฑ์„ ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋กœ ๋ชจ์œผ์ž.
  • null ๊ฐ’์„ ๊ฒฝ๊ณ„๋กœ ๋‘๋Š”๊ฒƒ๊ณผ ๋น„์Šทํ•˜๊ตฌ๋งŒ!

string ํƒ€์ž…๋ณด๋‹ค ๋” ๊ตฌ์ฒด์ ์ธ ํƒ€์ž… ์‚ฌ์šฉํ•˜๊ธฐ

  1. ๋ณ€์ˆ˜์˜ ๋ฒ”์œ„๋ฅผ ๋ณด๋‹ค ์ •ํ™•ํ•˜๊ฒŒ ํ‘œํ˜„ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด string ํƒ€์ž… ๋ณด๋‹ค๋Š” ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…์˜ ์œ ๋‹ˆ์˜จ ํƒ€์ž…์„ ์‚ฌ์šฉํ•ฉ์‹œ๋‹ค.
  2. ๊ฐ์ฒด ์†์„ฑ ์ด๋ฆ„์„ ํ•จ์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์„ ๋•Œ๋Š” string ๋ณด๋‹ค keyof T ๋ฅผ ์‚ฌ์šฉํ•ฉ์‹œ๋‹ค.
function pluck(records: any[], key: string): any[] {
  return records.map((r) => r[key]);
}

ํƒ€์ž…์‹œ๊ทธ๋‹ˆ์ฒ˜ ๊ฐœ์„  1 ๋ฒˆ

function pluck<T>(records: T[], key: string): any[] {
  return records.map((r) => r[key]);
}
  • ์—๋Ÿฌ๋‚จ
  • key ํƒ€์ž…์ด string ์ด๋ผ์„œ ๋„ˆ๋ฌด ๋„“์–ด์„œ.

๊ฐœ์„  3๋ฒˆ

function pluck<T>(records: T[], key: keyof T): T[keyof T][] {
  return records.map((r) => r[key]);
}
  • ํ•˜์ง€๋งŒ.. ๋งŒ์•ฝ T[โ€˜dateโ€™] ๋Š” ํƒ€์ž…์ด Date ์ด๊ตฌ.. T[โ€˜titleโ€™] ํƒ€์ž…์ด String ์ด๋ผ๋ฉด.. ์œ„์˜ T[keyof T][] ํƒ€์ž…์€ (string | Date) [] ์ด ๋œ๋‹ค.
  • ๊ทธ๋Ÿฐ๋ฐโ€ฆ key ๊ฐ’์ด ํ•˜๋‚˜๋งŒ ๋“ค์–ด๊ฐ€๋ฉด, ์ฆ‰ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋งŒ์•ฝ โ€˜dateโ€™ ๋งŒ ๋“ค์–ด๊ฐ€๋Š”๋ฐ ๋ฐ˜ํ™˜ํƒ€์ž…์ด (string | Date) [] ์ธ๊ฑฐ๋ฉด ๋„ˆ๋ฌด ๋„“๋‹ค!
  • ๋”ฐ๋ผ์„œ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ keyof T ์˜ ๋ถ€๋ถ„์ง‘ํ•ฉ์œผ๋กœ ๋‘๋ฒˆ์งธ ์ œ๋„ˆ๋ฆญ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋„ฃ์ž

๊ฐœ์„  2๋ฒˆ

function pluck<T, K extends keyof T>(records: T[], key: K): T[K][] {
  return records.map((r) => r[key]);
}

๋ถ€์ •ํ™•ํ•œ ํƒ€์ž…๋ณด๋‹ค๋Š” ๋ฏธ์™„์„ฑ์˜ ํƒ€์ž… ์‚ฌ์šฉํ•˜๊ธฐ

  • ํƒ€์ž…์ด ์—†๋Š” ๊ฒƒ ๋ณด๋‹ค ๋ถ€์ •ํ™•ํ•œ๊ฒŒ ๋” ๋‚˜์˜๋‹ค.
  • ์ •ํ™•ํ•˜๊ฒŒ ํƒ€์ž…์„ ๋ชจ๋ธ๋ง ํ•  ์ˆ˜ ์—†๋‹ค๋ฉด, ๋ถ€์ •ํ™•ํ•˜๊ฒŒ๋„ ๋ชจ๋ธ๋งํ•˜์ง€๋ง์ž.

๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹Œ, API ์™€ ๋ช…์„ธ๋ฅผ ๋ณด๊ณ  ํƒ€์ž… ๋งŒ๋“ค๊ธฐ

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

ํ•ด๋‹น๋ถ„์•ผ์˜ ์šฉ์–ด๋กœ ํƒ€์ž… ์ด๋ฆ„ ์ง“๊ธฐ

  • ์ž์ฒด์ ์œผ๋กœ ์šฉ์–ด๋ฅผ ๋งŒ๋“ค์–ด ๋‚ด๋ ค๊ณ  ํ•˜์ง€ ๋ง๊ณ , ํ•ด๋‹น ๋ถ„์•ผ์— ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์šฉ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์ž.
  • ๋™์ผํ•œ ์˜๋ฏธ๋ฅผ ๋‚˜ํƒ€๋‚ผ ๋•Œ๋Š” ๊ฐ™์€ ์šฉ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์ž.
  • data, info, thing, item, object, entity ์™€ ๊ฐ™์€ ๋ชจํ˜ธํ•˜๊ณ  ์˜๋ฏธ ์—†๋Š” ์ด๋ฆ„์€ ํ”ผํ•˜์ž.
  • ์ด๋ฆ„์„ ์ง€์„ ๋•Œ๋Š” ํฌํ•จ๋œ ๋‚ด์šฉ์ด๋‚˜, ๊ณ„์‚ฐ ๋ฐฉ์‹์ด ์•„๋‹ˆ๋ผ ๋ฐ์ดํ„ฐ ์ž์ฒด๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๊ณ ๋ คํ•˜์ž. INodeList ๋ณด๋‹ค Directory ๊ฐ€ ๋” ์˜๋ฏธ์žˆ๋Š” ์ด๋ฆ„์ด๋‹ค.
    • ์™œ? Directory ๋Š” ๊ตฌํ˜„์˜ ์ธก๋ฉด์ด ์•„๋‹ˆ๋ผ ๊ฐœ๋…์ ์ธ ์ธก๋ฉด์—์„œ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ƒ๊ฐํ•˜๊ฒŒ ํ•œ๋‹ค.
    • ์ข‹์€ ์ด๋ฆ„์€ ์ถ”์ƒํ™”์˜ ์ˆ˜์ค€์„ ๋†’์ด๊ณ , ์˜๋„์น˜ ์•Š์€ ์ถฉ๋Œ์˜ ์œ„ํ—˜์„ฑ์„ ๋‚ฎ์ถ˜๋‹ค.

๊ณต์‹ ๋ช…์นญ์—๋Š” ์ƒํ‘œ๋ฅผ ๋ถ™์ด๊ธฐ

  • ๊ตฌ์กฐ์  ํƒ€์ดํ•‘์˜ ํŠน์„ฑ ๋•Œ๋ฌธ์— ์ฝ”๋“œ๊ฐ€ ์ด์ƒํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋‚ผ ์ˆ˜ ์žˆ๋‹ค.
interface Vector2D {
  x: number;
  y: number;
}

function calculateNorm(p: Vector2D) {}

const vec3D = { x: 3, y: 4, z: 1 };
calculateNorm(vec3D); // ์ •์ƒ!!
  • ์ˆ˜ํ•™์ ์œผ๋กœ๋Š” 2์ฐจ์› ๋ฒกํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ์ด์น˜์— ๋งž๋Š”๋‹ค.
  • calculateNorm ํ•จ์ˆ˜๊ฐ€ 3์ฐจ์› ๋ฒกํ„ฐ๋ฅผ ํ—ˆ์šฉํ•˜์ง€ ์•Š๊ฒŒ ํ•˜๋ ค๋ฉด ๊ณต์‹ ๋ช…์นญ(Nominal typing) ์„ ์‚ฌ์šฉํ•˜์ž
  • ๊ณต์‹ ๋ช…์นญ์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์€, ํƒ€์ž…์ด ์•„๋‹ˆ๋ผ ๊ฐ’์˜ ๊ด€์ ์—์„œ Vector2D ๋ผ๊ณ  ๋งํ•˜๋Š” ๊ฒƒ!
interface Vector2D {
  _brand: '2D';
  x: number;
  y: number;
}

function calculateNorm(p: Vector2D) {}

const vec3D = { x: 3, y: 4, z: 1 };
calculateNorm(vec3D); // _brand ์†์„ฑ์ด ํ˜•์‹์— ์—†์Šต๋‹ˆ๋‹ค.
  • ๋ธŒ๋žœ๋”ฉ ๊ธฐ๋ฒ•์€ ํƒ€์ž… ์‹œ์Šคํ…œ์—์„œ ๋™์ž‘ํ•˜์ง€๋งŒ, ๋Ÿฐํƒ€์ž„์— ๋ธŒ๋žœ๋“œ๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ ํšจ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.
  • ํƒ€์ž…์‹œ์Šคํ…œ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋Ÿฐํƒ€์ž„ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๊ณ , ์ถ”๊ฐ€์†์„ฑ์„ ๋ถ™์ผ ์ˆ˜ ์—†๋Š” string ์ด๋‚˜ number์™€ ๊ฐ™์€ ๋‚ด์žฅ ํƒ€์ž…๋„ ์ƒํ‘œํ™”ํ• ์ˆ˜ ์žˆ๋‹ค.
type AbsoultePath = string & { _brand: 'abs' };

function listAbsolutePath(path: AbsoultePath) {
  // ..
}

function isAbsolutePath(path: string): path is AbsoultePath {
  return path.startsWith('/');
}

function f(path: string) {
  if (isAbsolutePath(path)) {
    listAbsolutePath(path);
  }
  listAbsolutePath(path); // error
}
  • ์ด๋Ÿฐ ์‹์œผ๋กœ ์ƒํ‘œ(brand)๋ฅผ ๋ถ™์—ฌ์„œ, ํƒ€์ž…์ด ํŠน์ •ํ•œ ์„ฑ๊ฒฉ์„ ๊ฐ€์กŒ๋Š”์ง€ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ด๋Š”, ๋Ÿฐํƒ€์ž„์— if ๋ฌธ์œผ๋กœ ์ฒดํฌํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ํšจ๊ณผ๋ฅผ ๋‚ด์ง€๋งŒ, ๋Ÿฐํƒ€์ž„์ด ์•„๋‹ˆ๋ผ ํƒ€์ž…์‹œ์Šคํ…œ์œผ๋กœ ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋Ÿฐํƒ€์ž„ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์—†๋‹ค!

any ํƒ€์ž…์€ ๊ฐ€๋Šฅํ•œ ํ•œ ์ข์€ ๋ฒ”์œ„์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๊ธฐ

type Bar = 'example';
function processBar(b: Bar) {}

function f1() {
  const x: any = 'foo';
  processBar(x); // ์ด๋ ‡๊ฒŒ ํ•˜์ง€๋งˆ์‹œ์˜ค
}

function f2() {
  const x = 'foo';
  processBar(x as any); // ์ด๊ฒŒ ๋‚ซ๋‹ค.
}
  • ์™œ 2๋ฒˆ์ด ๋‚ซ๋Š”๊ฐ€..?
  • 2๋ฒˆ์—์„œ any ํƒ€์ž…์€ processBar ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์—์„œ๋งŒ ์‚ฌ์šฉ๋œ ํ‘œํ˜„์‹์ด๋ฏ€๋กœ ๋‹ค๋ฅธ ์ฝ”๋“œ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ์ฆ‰, f1 ์—์„œ ํ•จ์ˆ˜์˜ ๋งˆ์ง€๋ง‰๊นŒ์ง€ x ์˜ ํƒ€์ž…์ด any ์ธ ๋ฐ˜๋ฉด, f2 ์—์„œ๋Š” processBar ํ˜ธ์ถœ ์ดํ›„ x ๊ฐ€ ๋‹ค์‹œ ์›๋ž˜ ํƒ€์ž…์œผ๋กœ ๋Œ์•„๊ฐ„๋‹ค.
  • ๋˜ํ•œ f1 ์—์„œ ์„ค์ƒ๊ฐ€์ƒ x ๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค๋ฉด..?! -> ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ๊ณณ์—์„œ any ํƒ€์ž…์ด ์ „์—ผ๋ณ‘์ฒ˜๋Ÿผ ํผ์ง„๋‹ค.
  • ๋น„์Šทํ•œ ๊ด€์ ์—์„œ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๊ฐ€ ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ์ถ”๋ก  ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์—๋„ ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ๋ช…์‹œํ•ด์•ผ ํ•œ๋‹ค. ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ๋ช…์‹œํ•˜์—ฌ any ํƒ€์ž…์ด ํ•จ์ˆ˜ ๋ฐ”๊นฅ์œผ๋กœ ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

any ๋ฅผ ๊ตฌ์ฒด์ ์œผ๋กœ ๋ณ€ํ˜•ํ•ด์„œ ์‚ฌ์šฉํ•˜๊ธฐ

  • any ๋ฅผ ์‚ฌ์šฉ ํ•  ๋•Œ๋Š” ์ •๋ง ๋ชจ๋“  ๊ฐ’์ด ํ—ˆ์šฉ๋˜์–ด์•ผ ํ•˜๋Š”์ง€ ๊ฒ€ํ† ํ•˜๊ณ  ์‚ฌ์šฉํ•˜๊ธฐ.
  • any ๋ณด๋‹ค ์ •ํ™•ํ•˜๊ฒŒ ๋ชจ๋ธ๋ง ํ•  ์ˆ˜ ์žˆ๋„๋ก any[] ๋˜๋Š” {[id:string]:any} ๋ฅผ ์‚ฌ์šฉํ•˜์ž

{[key: string]: any} ์™€ object ํƒ€์ž…์˜ ์ฐจ์ด์ 

  • object ํƒ€์ž…์€ ๊ฐ์ฒด์˜ ํ‚ค๋ฅผ ์—ด๊ฑฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์†์„ฑ์— ์ ‘๊ทผ ํ•  ์ˆ˜ ์—†๋‹ค.

ํ•จ์ˆ˜ ์•ˆ์œผ๋กœ ํƒ€์ž… ๋‹จ์–ธ๋ฌธ ๊ฐ์ถ”๊ธฐ

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

any ์˜ ์ง„ํ™”๋ฅผ ์ดํ•ดํ•˜๊ธฐ

  • any ๊ฐ€ ์ง„ํ™”ํ•œ๋‹ค๋Š” ๊ฒƒ์€, ์›๋ž˜ any ํƒ€์ž…์ด ์ฝ”๋“œ์— ๋”ฐ๋ผ์„œ ํŠน์ • ํƒ€์ž…์œผ๋กœ ์ขํ˜€์ง€๋Š” ํ˜„์ƒ!

any ์ง„ํ™”๋˜๋Š” ๊ฒฝ์šฐ

  • ์•”์‹œ์  any ํƒ€์ž…์— ์–ด๋–ค ๊ฐ’์„ ํ• ๋‹น ํ•  ๋•Œ any ๊ฐ€ ํŠน์ • ํƒ€์ž…์œผ๋กœ ์ขํ˜€์ ธ์„œ ์ง„ํ™”ํ•œ๋‹ค.

  • ํ•˜์ง€๋งŒ, ์–ด๋–ค ๋ณ€์ˆ˜๊ฐ€ ์•”์‹œ์  any ์ƒํƒœ์ผ ๋•Œ ๊ฐ’์„ ์ฝ์œผ๋ ค๊ณ  ํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

  • ๋ช…์‹œ์ ์œผ๋กœ any ๋ฅผ ์„ ์–ธํ•œ ๊ฒฝ์šฐ any ์ง„ํ™”๊ฐ€ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.

  • ์•”์‹œ์  any ํƒ€์ž…์€ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด๋„ ์ง„ํ™”ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์˜ค๋กœ์ง€ ๊ฐ’ ํ• ๋‹น์œผ๋กœ ์ง„ํ™”ํ•œ๋‹ค.

  • any ๋ฅผ ์ง„ํ™”์‹œํ‚ค๋Š” ๋ฐฉ์‹ ๋ณด๋‹ค ๋ช…์‹œ์  ํƒ€์ž… ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•œ ํƒ€์ž…์„ ์œ ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค!

๋ชจ๋ฅด๋Š” ํƒ€์ž…์˜ ๊ฐ’์—๋Š” any ๋Œ€์‹  unknown ์„ ์‚ฌ์šฉํ•˜๊ธฐ

any ํƒ€์ž…

  • ์–ด๋– ํ•œ ํƒ€์ž…์ด๋“  any ํƒ€์ž…์— ํ• ๋‹น ๊ฐ€๋Šฅํ•˜๋‹ค.
  • any ํƒ€์ž…์€ ์–ด๋– ํ•œ ํƒ€์ž…์œผ๋กœ๋„ ํ• ๋‹น ๊ฐ€๋Šฅํ•˜๋‹ค. (never ์˜ˆ์™ธ)

unknown ํƒ€์ž…

  • ์–ด๋– ํ•œ ํƒ€์ž…์ด๋“  unknown ํƒ€์ž…์— ํ• ๋‹น ๊ฐ€๋Šฅํ•˜๋‹ค.
  • unknown ์€ ์˜ค๋กœ์ง€ unknown ๊ณผ any ์—๋งŒ ํ• ๋‹น ๊ฐ€๋Šฅํ•˜๋‹ค.

any, unknown, never ์ฐจ์ด

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

๋ชฝํ‚ค ํŒจ์น˜ ๋ณด๋‹ค๋Š” ์•ˆ์ „ํ•œ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๊ธฐ

  • ๋ชฝํ‚คํŒจ์น˜๋ž€, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๊ฐ์ฒด์™€ ํด๋ž˜์Šค์— ์ž„์˜์˜ ์†์„ฑ์„ ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ธฐ๋Šฅ!
document.monkey = 'Hey';
// Error

// ์ข‹์ง€ ๋ชปํ•œ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•1 any ๋‹จ์–ธ๋ฌธ ์‚ฌ์šฉํ•˜๊ธฐ
(document as any).monkey = 'Hey';
  • ํ•˜์ง€๋งŒ ์ตœ์„ ์˜ ํ•ด๊ฒฐ์ฑ…์€ document ํ˜น์€ DOM ์œผ๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
  • ๋ถ„๋ฆฌํ•  ์ˆ˜ ์—†์„ ๊ฒฝ์šฐ ๋‘๊ฐ€์ง€ ํ•ด๊ฒฐ์ฑ…์ด ์กด์žฌํ•œ๋‹ค.
  1. interface ํŠน์ˆ˜ ๊ธฐ๋Šฅ์ธ โ€˜๋ณด๊ฐ•โ€™ ์‚ฌ์šฉํ•˜๊ธฐ
interface Document {
  monkey: string;
}
  • ํƒ€์ž…์ด ๋” ์•ˆ์ „ํ•˜๋‹ค.
  • ๋ชฝํ‚คํŒจ์น˜๊ฐ€ ์–ด๋–ค ๋ถ€๋ถ„์— ์ ์šฉ๋˜์—ˆ๋Š”์ง€ ์ •ํ™•ํ•œ ๊ธฐ๋ก์ด ๋‚จ๋Š”๋‹ค.
  • ์†์„ฑ์— ์ž๋™์™„์„ฑ์„ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ชจ๋“ˆ ๊ด€์ ์—์„œ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด global ์„ ์–ธ์„ ์ถ”๊ฐ€ํ•ด์•ผํ•œ๋‹ค.
declare global {
  interface Document {
    monkey: string;
  }
}
  • ํ•˜์ง€๋งŒ ์œ„์™€ ๊ฐ™์ด ๋ณด๊ฐ•์„ ์ „์—ญ์ ์œผ๋กœ ์ ์šฉํ•˜๋ฉด ์ฝ”๋“œ์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„์ด๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ๋ถ€ํ„ฐ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์—†๋‹ค.
  • ๊ทธ๋ฆฌ๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹คํ–‰๋˜๋Š” ๋™์•ˆ ์†์„ฑ์„ ํ• ๋‹นํ•˜๋ฉด ์‹คํ–‰ ์‹œ์ ์—์„œ ๋ณด๊ฐ•์„ ์ ์šฉํ•  ๋ฐฉ๋ฒ•์ด ์—†๋‹ค ใ… ใ… 
  • ํŠนํžˆ ์›น ํŽ˜์ด์ง€ ๋‚ด HTML ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์กฐ์ž‘ํ•  ๋•Œ, ์–ด๋–ค ์—˜๋ฆฌ๋จผํŠธ๋Š” ์†์„ฑ์ด ์žˆ๊ณ , ์–ด๋–ค ์—˜๋ฆฌ๋จผํŠธ๋Š” ์†์„ฑ์ด ์—†๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค.
  1. ๋” ๊ตฌ์ฒด์ ์ธ ํƒ€์ž… ๋‹จ์–ธ๋ฌธ ์‚ฌ์šฉํ•˜๊ธฐ
interface MonkeyDocument extends Document {
  monkey: string;
}

(document as MonkeyDocument).monkey = 'hey';

devDependencies ์— typescript ์™€ @types ์ถ”๊ฐ€ํ•˜๊ธฐ

dependencies

  • ํ˜„์žฌ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋Š”๋ฐ ํ•„์ˆ˜์ ์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค

devDependencies

  • ํ˜„์žฌ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ฐœ๋ฐœํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜์ง€๋งŒ, ๋Ÿฐํƒ€์ž„์—๋Š” ํ•„์š” ์—†๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค

peerDependencies

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

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹œ์Šคํ…œ ๋ ˆ๋ฒจ๋กœ ์„ค์น˜ํ•˜์ง€ ์•Š๋Š” ์ด์œ 

  • ํŒ€์›๋“ค ๋ชจ๋‘๊ฐ€ ํ•ญ์ƒ ๋™์ผํ•œ ๋ฒ„์ „์„ ์„ค์น˜ํ•œ๋‹ค๋Š” ๋ณด์žฅ์ด ์—†๋‹ค.
  • ํ”„๋กœ์ ํŠธ๋ฅผ ์…‹์—… ํ•  ๋•Œ ๋ณ„๋„์˜ ๋‹จ๊ณ„๊ฐ€ ์ถ”๊ฐ€๋œ๋‹ค.

ํƒ€์ž… ์„ ์–ธ๊ณผ ๊ด€๋ จ๋œ ์„ธ ๊ฐ€์ง€ ๋ฒ„์ „ ์ดํ•ดํ•˜๊ธฐ

์„ธ๊ฐ€์ง€ ๋ฒ„์ „

  1. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋ฒ„์ „
  2. ํƒ€์ž… ์„ ์–ธ(@types)์˜ ๋ฒ„์ „
  3. ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์˜ ๋ฒ„์ „

TsDocs ์‚ฌ์šฉํ•˜๊ธฐ

  • ํƒ€์ž… ์ •์˜์— ์ฃผ์„์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๊ธฐ!
  • ๋„ˆ๋ฌด ์žฅํ™ฉํ•˜๊ฒŒ ์“ฐ์ง€ ๋ง๊ธฐ
  • ์ต์ŠคํฌํŠธ ๋œ ํ•จ์ˆ˜, ํด๋ž˜์Šค, ํƒ€์ž…์— ์ฃผ์„์„ ๋‹ฌ ๋•Œ๋Š” TSDocs ํ˜•ํƒœ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ
  • ์ฃผ์„์— ํƒ€์ž… ์ •๋ณด ํฌํ•จํ•˜์ง€ ์•Š๊ธฐ

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

  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ let ์ด๋‚˜ const ๋กœ ์„ ์–ธ๋œ ๋ณ€์ˆ˜๋Š” ๋ ‰์‹œ์ปฌ ์Šค์ฝ”ํ”„์ด์ง€๋งŒ, this ๋Š” ๋™์  ์Šค์ฝ”ํ”„์ด๋‹ค.
  • ์ฆ‰, ๋™์  ์Šค์ฝ”ํ”„์˜ ๊ฐ’์€ โ€˜์ •์˜๋œ ๋ฐฉ์‹โ€™์ด ์•„๋‹ˆ๋ผ โ€˜ํ˜ธ์ถœ๋œ ๋ฐฉ์‹โ€™์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง„๋‹ค!
class C {
  vals = [1, 2, 3];
  logSquares() {
    for (const val of this.vals) {
      console.log(vals * vals);
    }
  }
}

const c = new C();
const method = c.logSquares;
method(); // error

๊ทธ๋ฆฌ์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ๋ช…์‹œ์ ์œผ๋กœ this ๋ฅผ ๋ฐ”์ธ๋”ฉ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

class C {
  vals = [1, 2, 3];
  logSquares() {
    for (const val of this.vals) {
      console.log(vals * vals);
    }
  }
}

const c = new C();
const method = c.logSquares;
method.call(c); // ๋ฐ”์ธ๋”ฉ ใ…Žใ…Ž

์ฝœ๋ฐฑ ํ•จ์ˆ˜์—์„œ this ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋ฉด ํƒ€์ž… ๋ช…์‹œํ•ด์ฃผ๊ธฐ



function addKeyListener{
  el: HTMLElement,
    fn: (this: HTMLElement, e: (KeyboardEvent)=>void )
}

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

function double(x: number | string): number | string;
function double(x: any) {
  return x + x;
}
  • double ํ•จ์ˆ˜์— string ๋˜๋Š” number ํƒ€์ž…์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋“ค์–ด์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
  • ๊ทธ๋ž˜์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์˜ค๋ฒ„๋กœ๋”ฉ์„ ์‚ฌ์šฉํ•ด์„œ ์œ ๋‹ˆ์˜จ ํƒ€์ž…์„ ์ถ”๊ฐ€ํ–ˆ๋‹ค.
  • ํ•˜์ง€๋งŒ..๋ฌธ์ œ์ ์ด ์žˆ๋‹ค.
  • string ํƒ€์ž…์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋„ฃ์œผ๋ฉด ๋ฐ˜ํ™˜์€ string ์ด ๋œ๋‹ค. vice versa
  • but.. ์œ„์˜ ์˜ˆ์ œ์— ๋”ฐ๋ฅด๋ฉด string ํƒ€์ž…์„ ๋„ฃ์–ด๋„ number ๋ฐ˜ํ™˜ํƒ€์ž…์ด ๋˜๋Š” ๊ฒฝ์šฐ๋„ ํฌํ•จ๋˜์–ด ์žˆ๋‹ค.
  • ์ œ๋„ค๋ฆญ์„ ์‚ฌ์šฉํ•ด์„œ ํ•ด๊ฒฐํ•ด๋ณด์Ÿ!!
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"
  • ํƒ€์ž…์ด ๋„ˆ๋ฌด ๊ณผํ•˜๊ฒŒ ๊ตฌ์ฒด์ ์ด๋‹ค.
  • ๊ทธ๋Ÿฌ๋ฉด ์—ฌ๋Ÿฌ๊ฐ€์ง€ ํƒ€์ž… ์„ ์–ธ์œผ๋กœ ๋ถ„๋ฆฌํ•ด๋ณด์Ÿˆ!!
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 ํƒ€์ž…์˜ ๊ฐ’์œผ๋กœ๋Š” ์ž˜ ๋™์ž‘ํ•˜์ง€๋งŒ, ์œ ๋‹ˆ์˜จ ํƒ€์ž… ๊ด€๋ จํ•ด์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค.
function double(x: number): number;
function double(x: string): string;
function double(x: any) {
  return x + x;
}

const num = double(12); // ํƒ€์ž…์ด 12
const str = double('x'); // ํƒ€์ž…์ด "x"

function f(x: number | string) {
  return double(x); // Error 'string' | 'number' ํ˜•์‹์˜ ์ธ์ˆ˜๋Š”
  // 'string' ํ˜•์‹์˜ ๋งค๊ฐœ๋ณ€์ˆ˜์— ํ• ๋‹น๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค!!
}
  • ์™œ..?!
  • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” ์˜ค๋ฒ„๋กœ๋”ฉ ํƒ€์ž… ์ค‘์—์„œ ์ผ์น˜ํ•˜๋Š” ํƒ€์ž…์„ ์ฐพ์„ ๋•Œ ๊นŒ์ง€ ์ˆœ์ฐจ์ ์œผ๋กœ ๊ฒ€์ƒ‰ํ•œ๋‹ค.
  • ๊ทธ๋ž˜์„œ ์˜ค๋ฒ„๋กœ๋”ฉ ํƒ€์ž…์˜ ๋งˆ์ง€๋ง‰ ์„ ์–ธ(string ๋ฒ„์ „)๊นŒ์ง€ ๊ฒ€์ƒ‰ํ–ˆ์„ ๋•Œ, string| number ํƒ€์ž…์€ string ์— ํ• ๋‹น๋  ์ˆ˜ ์—†๋Š” ๊ฒƒ์ด๋‹ค..ใ…Žใ…Ž
  • ๊ทธ๋Ÿฌ๋ฉด ์„ธ๋ฒˆ์งธ์— ์˜ค๋ฒ„๋กœ๋”ฉ ํƒ€์ž…์— ์œ ๋‹ˆ์˜จํƒ€์ž…์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋˜์ง€ ์•Š์„๊นŒ?! -> ๋งจ ์ฒ˜์Œ ๋ฌธ์ œ.. string ์ธ์ˆ˜ -> number ๋ฐ˜ํ™˜ (vice versa) ๊ฐ€ ๋‚จ์•„์žˆ์Œ
  • ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ๋ฐ”๋กœ ์กฐ๊ฑด๋ถ€ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ!

์กฐ๊ฑด๋ถ€ ํƒ€์ž… ์‚ฌ์šฉํ•˜๊ธฐ

function double<T extends number | string>(x: T): T extends string ? string : number;
function double(x: any) {
  return x + x;
}
  • T ๊ฐ€ string ์˜ ๋ถ€๋ถ„์ง‘ํ•ฉ์ด๋ฉด ๋ฐ˜ํ™˜ ํƒ€์ž…์ด string ์ด๋‹ค
  • ๊ทธ ์™ธ์˜ ๊ฒฝ์šฐ๋Š” ๋ฐ˜ํ™˜ ํƒ€์ž…์ด number ์ด๋‹ค.