03. ๐Ÿ›ก๏ธ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ๊ณ ๊ธ‰ ํƒ€์ž… ์„ค๊ณ„์™€ ์ถ”๋ก 

2026๋…„ 3์›” 5์ผ ์ˆ˜์ •๋จ

๐Ÿ“‹ ๊ฐœ์š”

๋‹จ์ˆœํ•œ ํƒ€์ž… ์„ ์–ธ์„ ๋„˜์–ด, ์กฐ๊ฑด๋ถ€ ํƒ€์ž…๊ณผ ์ œ๋„ค๋ฆญ์„ ํ™œ์šฉํ•œ ๊ณ ๋„๋กœ ์œ ์—ฐํ•˜๊ณ  ์•ˆ์ „ํ•œ ํƒ€์ž… ์„ค๊ณ„ ๋Šฅ๋ ฅ์„ ๋ฐฐ์–‘ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ ์ด ๋ฉด์ ‘ ํ•ญ๋ชฉ์˜ ๋ชฉํ‘œ

โฑ๏ธ ์˜ˆ์ƒ ์ฝ๊ธฐ ์‹œ๊ฐ„: 20๋ถ„ (ํ•ต์‹ฌ ์š”์•ฝ: 10๋ถ„)

๐Ÿ—บ๏ธ ์ด ์ฑ•ํ„ฐ์˜ ํ๋ฆ„
[๊ฐœ๋… ์‚ฌ์ „] โ†’ [์งˆ๋ฌธ 1: ์ปดํฌ๋„ŒํŠธ ๋‹คํ˜•์„ฑ ์„ค๊ณ„] โ†’ [์งˆ๋ฌธ 2: ์กฐ๊ฑด๋ถ€ ํƒ€์ž… & infer] โ†’ [์—ฐ๊ด€ ๋ณ€ํ˜• ์งˆ๋ฌธ]

๐ŸŽฏ ์ด ์ฑ•ํ„ฐ๋ฅผ ๋‹ค ์ฝ์œผ๋ฉด ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ

  • ์œ ๋‹ˆ์–ธ๊ณผ ๊ต์ฐจ ํƒ€์ž…์„ ํ™œ์šฉํ•ด ๊ฒฐํ•ฉ๋„๊ฐ€ ๋‚ฎ๊ณ  ์•ˆ์ „ํ•œ Props๋ฅผ ์„ค๊ณ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Conditional Types์™€ infer๋ฅผ ์‚ฌ์šฉํ•ด ๋ณต์žกํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ˆ˜์ค€์˜ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํƒ€์ž…์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
  • any ๋Œ€์‹  unknown๊ณผ satisfies๋ฅผ ์จ์•ผ ํ•˜๋Š” ์ƒํ™ฉ์„ ๋…ผ๋ฆฌ์ ์œผ๋กœ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“š ํ•ต์‹ฌ ๊ฐœ๋… ์‚ฌ์ „ (Concept Glossary)

1. ์ œ๋„ค๋ฆญ (Generics)

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

2. ์กฐ๊ฑด๋ถ€ ํƒ€์ž… (Conditional Types)

T extends U ? X : Y ํ˜•ํƒœ๋กœ, ํƒ€์ž… ์‹œ์Šคํ…œ ๋‚ด์—์„œ '์กฐ๊ฑด๋ฌธ'์„ ์‹คํ–‰ํ•˜๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ์ž…๋ ฅ ํƒ€์ž…์— ๋”ฐ๋ผ ๊ฒฐ๊ณผ ํƒ€์ž…์„ ๋™์ ์œผ๋กœ ๊ฒฐ์ •ํ•  ๋•Œ ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค.

3. infer ํ‚ค์›Œ๋“œ

์กฐ๊ฑด๋ถ€ ํƒ€์ž… ๋‚ด์—์„œ ์ถ”๋ก ํ•  ํƒ€์ž…์— ์ด๋ฆ„์„ ๋ถ™์ด๋Š” ๋งˆ๋ฒ• ๊ฐ™์€ ํ‚ค์›Œ๋“œ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด ํƒ€์ž…์ด๋‚˜ ๋ฐฐ์—ด์˜ ์š”์†Œ ํƒ€์ž…์„ ๋Ÿฐํƒ€์ž„์ด ์•„๋‹Œ ํƒ€์ž… ์—”์ง„ ๋‹จ์—์„œ ๋ฝ‘์•„๋‚ผ ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ๋ฐฐ๊ฒฝ ์„ธ๊ณ„๊ด€: '์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ'

  • ๐Ÿฃ ์˜์ฒ  ( ์‹ ์ž… ): "์˜ํ˜ธ ๋‹˜! '์˜์ˆ˜๋„ค ํ†ตํ•ฉ ๋ฒ„ํŠผ' ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ, <a> ํƒœ๊ทธ๋กœ ์“ฐ์ผ ๋•Œ๋ž‘ <button>์œผ๋กœ ์“ฐ์ผ ๋•Œ Props ํƒ€์ž…์„ ๋‹ค๋ฅด๊ฒŒ ์ฃผ๊ธฐ๊ฐ€ ๋„ˆ๋ฌด ํž˜๋“ค์–ด์š”. ๊ทธ๋ƒฅ any ๋ฐ•์œผ๋ฉด ์•ˆ ๋ ๊นŒ์š”? ๐Ÿ˜…"
  • ๐Ÿฆ ์˜ํ˜ธ ( ๋ฆฌ๋“œ ): "์˜์ฒ  ๋‹˜, any๋ฅผ ๋ฐ•๋Š” ์ˆœ๊ฐ„ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋ฅผ ์“ฐ๋Š” ์˜๋ฏธ๊ฐ€ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. ๊ทธ๊ฑด '์•ˆ์ „ ๋ฒจํŠธ๋ฅผ ์ž๋ฅด๊ณ  ์šด์ „ํ•˜๊ฒ ๋‹ค'๋Š” ์†Œ๋ฆฌ์˜ˆ์š”. ์œ ๋‹ˆ์–ธ ํƒ€์ž…๊ณผ ์ œ๋„ค๋ฆญ๋งŒ ์žˆ์œผ๋ฉด ํ›จ์”ฌ ์šฐ์•„ํ•˜๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ๋ง์ด์ฃ . ๋ฉด์ ‘์—์„œ ์ด๋Ÿฐ '์„ค๊ณ„ ๊ณ ๋ฏผ'์„ ๋ณด์—ฌ์ค˜์•ผ ์‹œ๋‹ˆ์–ด๋กœ ์ธ์ •๋ฐ›๋Š” ๊ฒ๋‹ˆ๋‹ค."

Q1. ์œ ๋‹ˆ์–ธ ํƒ€์ž…๊ณผ ๊ต์ฐจ ํƒ€์ž…์„ ํ™œ์šฉํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ์˜ props ๋‹คํ˜•์„ฑ์„ ์•ˆ์ „ํ•˜๊ฒŒ ์„ค๊ณ„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ด ๋ณด์„ธ์š”.

๐ŸŽฏ ์ถœ์ œ ์˜๋„

๋‹จ์ˆœํžˆ interface๋ฅผ ์ •์˜ํ•˜๋Š” ์ˆ˜์ค€์„ ๋„˜์–ด, ์„œ๋กœ ๋ฐฐํƒ€์ ์ธ ์†์„ฑ ๊ด€๊ณ„๋ฅผ ํƒ€์ž…์œผ๋กœ ๊ฐ•์ œํ•  ์ˆ˜ ์žˆ๋Š”์ง€(Discriminated Unions) ์„ค๊ณ„ ์—ญ๋Ÿ‰์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

๐Ÿฃ ์˜์ฒ ์ด์˜ Naive ๊ตฌํ˜„ (Bad Case)

์˜์ฒ ์ด๋Š” ๋ชจ๋“  ์†์„ฑ์„ ์˜ต์…”๋„(?)๋กœ ๋งŒ๋“ค์–ด์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ๋ฅผ ๋ฐฉ์ง€ํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

// ๐Ÿฃ ์˜์ฒ : "์žˆ๋Š” ๊ฒƒ๋งŒ ์“ฐ๋ฉด ๋˜๋‹ˆ๊นŒ ๋‹ค ์˜ต์…”๋„๋กœ ํ•˜๋ฉด ํŽธํ•˜๊ฒ ์ฃ ?"
interface ButtonProps {
  label: string;
  onClick?: () => void; // ๋ฒ„ํŠผ์ผ ๋•Œ ํ•„์ˆ˜
  href?: string;        // ๋งํฌ์ผ ๋•Œ ํ•„์ˆ˜
}
 
// โš ๏ธ ๋ฒ„๊ทธ ๋ฐœ์ƒ: href๊ฐ€ ์—†๋Š”๋ฐ ๋งํฌ๋กœ ๋™์ž‘ํ•˜๊ฑฐ๋‚˜, onClick์ด ์—†๋Š”๋ฐ ๋ฒ„ํŠผ์ธ ๊ฒฝ์šฐ๋ฅผ ๋ง‰์ง€ ๋ชปํ•จ
<Button label="ํด๋ฆญ" /> // ์•„๋ฌด ๋™์ž‘ ์•ˆ ํ•จ

๐Ÿฆ ์˜ํ˜ธ์˜ ํŒฉํญ ์กฐ์–ธ
"์˜์ฒ  ๋‹˜, ์ด๋ ‡๊ฒŒ ์งœ๋ฉด ์‚ฌ์šฉ์ž๋Š” ๋ฌธ์„œ๋ฅผ ๋‹ค ์ฝ์–ด์•ผ๋งŒ ์ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ์“ธ ์ˆ˜ ์žˆ์–ด์š”. ํƒ€์ž… ์‹œ์Šคํ…œ์ด '์ด๊ฑด ๋ฒ„ํŠผ์ด๋‹ˆ๊นŒ href๋Š” ๋„ฃ์ง€ ๋งˆ!'๋ผ๊ณ  ๋งํ•ด์ค˜์•ผ์ฃ . ์ด๊ฒƒ์ด ๋ฐ”๋กœ ๋™์  ๋‹คํ˜•์„ฑ์˜ ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค."

๐Ÿฆ ์˜ํ˜ธ์˜ ์•„ํ‚คํ…์ฒ˜ ๊ฐ€์ด๋“œ (Good Case)

์˜ํ˜ธ ๋ฆฌ๋“œ๋Š” Discriminated Unions๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํƒ€์ž…์ด ์‚ฌ์šฉ์ž๋ฅผ ๊ฐ€์ด๋“œํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

// ๐Ÿฆ ์˜ํ˜ธ: "ํƒ€์ž…์ด ์Šค์Šค๋กœ์˜ ์šฉ๋„๋ฅผ ์ฆ๋ช…ํ•˜๊ฒŒ ํ•˜์„ธ์š”."
type BaseProps = { label: string };
 
type ButtonProps = BaseProps & {
  as: 'button';
  onClick: () => void; // ํ•„์ˆ˜
  href?: never;        // ์ ˆ๋Œ€ ์˜ค๋ฉด ์•ˆ ๋จ
};
 
type LinkProps = BaseProps & {
  as: 'a';
  href: string;        // ํ•„์ˆ˜
  onClick?: never;
};
 
type PolymorphicProps = ButtonProps | LinkProps;
 
function CustomButton(props: PolymorphicProps) {
  // ... ๊ตฌํ˜„ ๋กœ์ง
}
 
// โœ… ์„ฑ๊ณต: as๊ฐ€ 'a'๋ฉด ์ž๋™ ์™„์„ฑ์œผ๋กœ href๋ฅผ ์š”๊ตฌํ•จ
<CustomButton as="a" href="/home" label="ํ™ˆ์œผ๋กœ" />

๐Ÿ“Š ๋ ˆ๋ฒจ๋ณ„ ๋‹ต๋ณ€ ๊ฐ€์ด๋“œ (Self-Check)

  • Level 1 (Junior): "์œ ๋‹ˆ์–ธ์€ | ๊ธฐํ˜ธ๋กœ ์—ฌ๋Ÿฌ ํƒ€์ž… ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด๊ณ , ๊ต์ฐจ๋Š” &๋กœ ํƒ€์ž…๋“ค์„ ํ•ฉ์น˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค."
  • Level 2 (Senior): "์œ ๋‹ˆ์–ธ ํƒ€์ž…์„ ํ™œ์šฉํ•œ Discriminated Union(์‹๋ณ„ ๊ฐ€๋Šฅํ•œ ์œ ๋‹ˆ์–ธ) ํŒจํ„ด์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๊ณตํ†ต ์†์„ฑ(tag, as ๋“ฑ)์„ ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…์œผ๋กœ ๋‘์–ด ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํƒ€์ž…์„ ์ขํž ์ˆ˜ ์žˆ๊ฒŒ ์„ค๊ณ„ํ•˜๋Š” ์‹ค๋ฌด ์‚ฌ๋ก€๋ฅผ ์ œ์‹œํ•ฉ๋‹ˆ๋‹ค."
  • Level 3 (Specialist): "์ œ๋„ค๋ฆญ์„ ํ™œ์šฉํ•œ Polymorphic Component ์„ค๊ณ„ ๊ธฐ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. HTML ํƒœ๊ทธ ์ข…๋ฅ˜์— ๋”ฐ๋ผ ์ž๋™์œผ๋กœ IntrinsicElements ํƒ€์ž…์„ ๋งคํ•‘ํ•ด์ฃผ์–ด, ์ปค์Šคํ…€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ธŒ๋ผ์šฐ์ € ํ‘œ์ค€ ์†์„ฑ๊นŒ์ง€ ์™„๋ฒฝํ•˜๊ฒŒ ์ง€์›ํ•˜๋„๋ก ๋งŒ๋“œ๋Š” ๊ณ ๋„ํ™”๋œ ์„ค๊ณ„๋ฅผ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค."

Q2. ์กฐ๊ฑด๋ถ€ ํƒ€์ž…(Conditional Types)๊ณผ infer ํ‚ค์›Œ๋“œ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ณต์žกํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํƒ€์ž…์„ ์ง์ ‘ ๊ตฌํ˜„ํ•ด ๋ณธ ๊ฒฝํ—˜์„ ์„ค๋ช…ํ•ด ๋ณด์„ธ์š”.

๐ŸŽฏ ์ถœ์ œ ์˜๋„

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

๐Ÿฃ ์˜์ฒ ์ด์˜ Naive ๊ตฌํ˜„ (Bad Case)

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

// ๐Ÿฃ ์˜์ฒ : "ํ•จ์ˆ˜๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ๋ฆฌํ„ด ํƒ€์ž…๋„ ์ˆ˜๋™์œผ๋กœ ๊ณ ์ณ์•ผ ํ•ด์„œ ๋ฒˆ๊ฑฐ๋กœ์›Œ์š”..."
function getUser() {
  return { id: 1, name: '์˜์ฒ ' };
}
 
type User = { id: number; name: string }; // โš ๏ธ ํ•จ์ˆ˜๊ฐ€ ๋ฐ”๋€Œ๋ฉด ์—ฌ๊ธฐ๋„ ๊ณ ์ณ์•ผ ํ•จ (์‹ฑํฌ ๋ฏธ์Šค ๊ฐ€๋Šฅ์„ฑ)

๐Ÿฆ ์˜ํ˜ธ์˜ ํŒฉํญ ์กฐ์–ธ
"์˜์ฒ  ๋‹˜, ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์—๊ฒŒ ์ง์ ‘ ๋ฌผ์–ด๋ณด์„ธ์š”. infer๋ฅผ ์“ฐ๋ฉด ํ•จ์ˆ˜์˜ ๋ฐฐ๋ฅผ ๊ฐˆ๋ผ(?) ๋ฆฌํ„ด ํƒ€์ž…์„ ์ง์ ‘ ๊บผ๋‚ด์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์“ฐ๋Š” ReturnType<T> ํ•˜๋“œ์›จ์–ด๊ฐ€ ๋ฐ”๋กœ ์ด๋ ‡๊ฒŒ ์ƒ๊ฒผ์ฃ ."

๐Ÿฆ ์˜ํ˜ธ์˜ ์•„ํ‚คํ…์ฒ˜ ๊ฐ€์ด๋“œ (Good Case)

์˜ํ˜ธ ๋ฆฌ๋“œ๊ฐ€ infer๋ฅผ ์‚ฌ์šฉํ•ด ์ง์ ‘ GetReturnType ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ๋งŒ๋“œ๋Š” ๊ณผ์ •์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

// ๐Ÿฆ ์˜ํ˜ธ: "ํƒ€์ž… ์—”์ง„์ด ์Šค์Šค๋กœ ์ถ”๋ก ํ•˜๊ฒŒ ๋งŒ๋“œ์„ธ์š”."
 
// T๊ฐ€ ํ•จ์ˆ˜๋ผ๋ฉด, ๊ทธ ๋ฆฌํ„ด ํƒ€์ž…์„ R๋กœ ์ถ”๋ก (infer)ํ•ด์„œ ๋ฐ˜ํ™˜ํ•˜๋ผ!
type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
 
function getBoardAction() {
    return { type: 'CREATE_POST', payload: '์˜ค๋Š˜๋„ ์ฝ”๋”ฉ!' };
}
 
// โœ… ์ด์ œ getBoardAction์ด ๋ฐ”๋€Œ์–ด๋„ ์ž๋™์œผ๋กœ ์ถ”๋ก ๋จ!
type Action = MyReturnType<typeof getBoardAction>;

๐Ÿ“Š ๋ ˆ๋ฒจ๋ณ„ ๋‹ต๋ณ€ ๊ฐ€์ด๋“œ (Self-Check)

  • Level 1 (Junior): "์กฐ๊ฑด๋ถ€ ํƒ€์ž…์€ ํƒ€์ž…ํŒ ์‚ผํ•ญ ์—ฐ์‚ฐ์ž๊ณ , infer๋Š” ํƒ€์ž…์„ ์ถ”๋ก ํ•  ๋•Œ ์”๋‹ˆ๋‹ค."
  • Level 2 (Senior): "infer๊ฐ€ ์˜ค์ง extends ์ ˆ์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์ œ์•ฝ์„ ์•Œ๊ณ  ์žˆ์œผ๋ฉฐ, Promise์˜ ๋‚ด๋ถ€ ๊ฐ’ ํƒ€์ž…์„ ๊บผ๋‚ด๊ฑฐ๋‚˜ ๋ฐฐ์—ด์˜ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ ํƒ€์ž…์„ ์ถ”์ถœํ•˜๋Š” ๊ตฌ์ฒด์ ์ธ ์˜ˆ์‹œ๋ฅผ ๋“ค์–ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค."
  • Level 3 (Specialist): "๋ถ„์‚ฐ ์กฐ๊ฑด๋ถ€ ํƒ€์ž…(Distributive Conditional Types)์˜ ํŠน์„ฑ์„ ์ดํ•ดํ•˜๊ณ , ์œ ๋‹ˆ์–ธ ํƒ€์ž…์ด ๋“ค์–ด์™”์„ ๋•Œ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ™œ์šฉํ•ด ํŠน์ • ์†์„ฑ๋งŒ ์ œ๊ฑฐํ•˜๋Š” Omit์ด๋‚˜ Exclude ๊ฐ™์€ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํƒ€์ž…์ด ๋‚ด๋ถ€์ ์œผ๋กœ ์–ด๋–ป๊ฒŒ ์žฌ๊ท€์ ์œผ๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ๋…ผ๋ฆฌ์ ์œผ๋กœ ๋ถ„์„ํ•ฉ๋‹ˆ๋‹ค."

Q9. ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์—์„œ ์ปดํŒŒ์ผ ํƒ€์ž„์— ์ œ๋„ค๋ฆญ(Generics)์˜ ํƒ€์ž… ์ถ”๋ก  ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋‚˜์š”?

  • ๐ŸŽฏ ์ถœ์ œ ์˜๋„: ์ œ๋„ค๋ฆญ์ด ๋‹จ์ˆœํžˆ ํƒ€์ž…์„ ๋ณต์‚ฌ-๋ถ™์—ฌ๋„ฃ๊ธฐ ํ•˜๋Š” ์ˆ˜์ค€์„ ๋„˜์–ด, ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ฐ์ดํ„ฐ์˜ ํ๋ฆ„์œผ๋กœ๋ถ€ํ„ฐ ํƒ€์ž…์„ ์—ญ์ถ”๋ก (Inference)ํ•˜๋Š”์ง€ ์‹ฌ๋„ ์žˆ๊ฒŒ ํŒŒ์•…ํ•ฉ๋‹ˆ๋‹ค.
  • ๐Ÿ’ก ํ•ต์‹ฌ ์›๋ฆฌ & ๋‹ต๋ณ€: ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ํ•จ์ˆ˜์— ์ „๋‹ฌ๋œ ์‹ค์ œ ์ธ์ž(Value)์˜ ํƒ€์ž…์„ ๋ณด๊ณ , ๊ทธ์™€ ๋งค์นญ๋œ ์ œ๋„ค๋ฆญ ํƒ€์ž… ๋ณ€์ˆ˜(T ๋“ฑ)๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ 'ํƒ€์ž… ์ธ์ˆ˜ ์ถ”๋ก '์ด๋ผ ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ธ์ž๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ๋ผ๋ฉด ๊ฐ ์ธ์ž์˜ ๊ณตํ†ต ๋ถ„๋ชจ(LUB, Least Upper Bound)๋ฅผ ์ฐพ์•„ ํƒ€์ž…์„ ์ขํž™๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ํƒ€์ž…์„ ์ ์ง€ ์•Š์•„๋„ ๋˜๋Š” ์ด์œ ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•˜ํ–ฅ์‹(Top-down) ๋ฐ ์ƒํ–ฅ์‹(Bottom-up) ์ถ”๋ก ์„ ๋ณ‘ํ–‰ํ•˜์—ฌ ๊ฐ€์žฅ ๊ตฌ์ฒด์ ์ธ ํƒ€์ž…์„ ์ฐพ์•„๋‚ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ดํ•ดํ•˜๋ฉด ๋ถˆํ•„์š”ํ•œ ํƒ€์ž… ๋‹จ์–ธ ์—†์ด๋„ ์•ˆ์ „ํ•œ ์ฝ”๋“œ๋ฅผ ์งค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Q23. unknown ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜์—ฌ ์•ˆ์ „ํ•˜๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ์บ์ŠคํŒ…ํ•˜๋Š” ์ „๋žต์„ ์„ค๋ช…ํ•ด ๋ณด์„ธ์š”.

  • ๐ŸŽฏ ์ถœ์ œ ์˜๋„: any๋ผ๋Š” ์น˜ํŠธํ‚ค ๋Œ€์‹ , ํƒ€์ž… ์‹œ์Šคํ…œ์„ ์กด์ค‘ํ•˜๋ฉฐ ๋ถˆํ™•์‹คํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” '์•ˆ์ „ํ•œ ๋ฐฉ์–ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ' ์—ญ๋Ÿ‰์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ๐Ÿ’ก ํ•ต์‹ฌ ์›๋ฆฌ & ๋‹ต๋ณ€: unknown์€ any์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ชจ๋“  ๊ฐ’์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” '์ตœ์ƒ์œ„ ํƒ€์ž…'์ด์ง€๋งŒ, any์™€ ๊ฒฐ์ •์ ์ธ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. unknown ํƒ€์ž…์˜ ๋ณ€์ˆ˜๋Š” ๊ทธ ์•ˆ์— ๋ฌด์—‡์ด ๋“ค์–ด์žˆ๋Š”์ง€ ํƒ€์ž… ๊ฐ€๋“œ(typeof, instanceof ๋“ฑ)๋กœ ๋ช…ํ™•ํžˆ ๊ฒ€์ฆํ•˜๊ธฐ ์ „๊นŒ์ง€๋Š” ์–ด๋– ํ•œ ์†์„ฑ ์ ‘๊ทผ์ด๋‚˜ ์—ฐ์‚ฐ๋„ ํ—ˆ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๊ฐœ๋ฐœ์ž์—๊ฒŒ "์ด ๊ฐ’์€ ์œ„ํ—˜ํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ ๋จผ์ € ํ™•์ธํ•˜๊ณ  ์จ!"๋ผ๊ณ  ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ฐ•์ œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์™ธ๋ถ€ API ์‘๋‹ต์ด๋‚˜ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์ฒ˜๋Ÿผ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ๋ฐ์ดํ„ฐ๋Š” ๋ฐ˜๋“œ์‹œ unknown์œผ๋กœ ์„ ์–ธํ•˜๊ณ  ๋Ÿฐํƒ€์ž„ ์ฒดํฌ๋ฅผ ๊ฑฐ์นœ ๋’ค ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋ชจ๋˜ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์˜ ํ‘œ์ค€ ์ •์„์ž…๋‹ˆ๋‹ค.

Q24. satisfies ์—ฐ์‚ฐ์ž๊ฐ€ ๋„์ž…๋œ ์ด์œ ์™€, as ํƒ€์ž… ๋‹จ์–ธ ๋ฐฉ์‹๊ณผ์˜ ์ฐจ์ด๋Š” ๋ฌด์—‡์ธ๊ฐ€์š”?

  • ๐ŸŽฏ ์ถœ์ œ ์˜๋„: ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ 4.9+ ๋ฒ„์ „์˜ ์ตœ์‹  ๊ธฐ๋Šฅ์„ ์ดํ•ดํ•˜๊ณ , ๊ฐ์ฒด์˜ ์ •๋ฐ€ํ•œ ํƒ€์ž… ์ •๋ณด(Literal Identity)๋ฅผ ์žƒ์ง€ ์•Š์œผ๋ฉด์„œ๋„ ๋ช…์„ธ์™€ ์ผ์น˜ํ•˜๋Š”์ง€ ๊ฒ€์ฆํ•˜๋Š” ๊ณ ๊ธ‰ ๊ธฐ์ˆ ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ๐Ÿ’ก ํ•ต์‹ฌ ์›๋ฆฌ & ๋‹ต๋ณ€: as๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ "๋‚ด๊ฐ€ ๋งž์œผ๋‹ˆ๊นŒ ์ž… ๋‹ค๋ฌผ์–ด"๋ผ๊ณ  ๊ฐ•์š”ํ•˜๋Š” 'ํƒ€์ž… ๋‹จ์–ธ'์ด๋ฉฐ, ์†์„ฑ ์ด๋ฆ„ ์˜คํƒ€ ๋“ฑ์ด ์žˆ์–ด๋„ ์žก์•„๋‚ด์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด satisfies๋Š” ํŠน์ • ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ์กฑํ•˜๋Š”์ง€ ๊ฒ€์‚ฌํ•˜๋ฉด์„œ๋„, ํ•ด๋‹น ๊ฐ์ฒด์˜ ๊ตฌ์ฒด์ ์ธ ๋ฆฌํ„ฐ๋Ÿด ์ •๋ณด๋ฅผ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ƒ‰์ƒ ๊ฐ์ฒด์— Record<string, string>์„ satisfiesํ•˜๋ฉด, ๊ฐ ์ƒ‰์ƒ ์ด๋ฆ„์ด ๋ฌด์—‡์ธ์ง€(์˜ˆ: 'red')๋ฅผ ํƒ€์ž… ์—”์ง„์ด ๊ธฐ์–ตํ•˜๋ฏ€๋กœ ๋‚˜์ค‘์— ์˜คํƒ€ ๊ฒ€์‚ฌ๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค. ๋ช…์‹œ์  ํƒ€์ž… ์„ ์–ธ๋ณด๋‹ค ํ›จ์”ฌ ์œ ์—ฐํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ ์ •์  ๋ถ„์„์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿฃ ์˜์ฒ ์ด์˜ ๋ณต๊ธฐ ์ผ๊ธฐ

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

๐Ÿ’ก "ํƒ€์ž…์€ ๋ฌธ์„œ๋‹ค. ์–ด๋–ค ๊ฐ’์„ ๋„ฃ์–ด์•ผ ํ•˜๊ณ  ๋ฌด์—‡์ด ๋‚˜์˜ค๋Š”์ง€ ์‚ฌ์šฉ์ž๊ฐ€ ๊ณ ๋ฏผํ•˜๊ฒŒ ๋งŒ๋“ค์ง€ ๋งˆ๋ผ."

๋‚ด์ผ์€ ๋ฆฌ์•กํŠธ์˜ ์‹ฌ์žฅ, '๋ Œ๋”๋ง ์—”์ง„'์„ ํŒŒํ—ค์ณ๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค. ์˜ํ˜ธ ๋‹˜์ด "Fiber ์•„ํ‚คํ…์ฒ˜ ๋ชจ๋ฅด๋ฉด 5๋…„ ์ฐจ๋ผ๊ณ  ํ•˜์ง€ ๋งˆ๋ผ"๊ณ  ํ•˜์…จ๋Š”๋ฐ... ๋–จ๋ฆฐ๋‹ค! ๐Ÿ’“