LearningTS Chapter 10 - YDP-SPLOUNGE-CLUB/typescript-study GitHub Wiki

10. μ œλ„€λ¦­

νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œ ν•¨μˆ˜μ™€ 같은 κ΅¬μ‘°μ²΄λŠ” μ œλ„€λ¦­ νƒ€μž… ꡬ쑰체λ₯Ό μ›ν•˜λŠ” 수만큼 μ„ μ–Έν•  수 μžˆλ‹€. μ œλ„€λ¦­ νƒ€μž… λ§€κ°œλ³€μˆ˜λŠ” μ œλ„€λ¦­ ꡬ쑰체의 각 μ‚¬μš©λ²•μ— 따라 νƒ€μž…μ΄ κ²°μ •λœλ‹€. μ΄λŸ¬ν•œ νƒ€μž… λ§€κ°œλ³€μˆ˜λŠ” ꡬ쑰체의 각 μΈμŠ€ν„΄μŠ€μ—μ„œ μ„œλ‘œ λ‹€λ₯Έ 일뢀 νƒ€μž…μ„ λ‚˜νƒ€λ‚΄κΈ° μœ„ν•΄ ꡬ쑰체의 νƒ€μž…μœΌλ‘œ μ‚¬μš©λœλ‹€.

μ΄λŸ¬ν•œ νƒ€μž… λ§€κ°œλ³€μˆ˜λŠ” ꡬ쑰체의 각 μΈμŠ€ν„΄μŠ€μ—μ„œ μ„œλ‘œ λ‹€λ₯Έ 일뢀 νƒ€μž…μ„ λ‚˜νƒ€λ‚΄κΈ° μœ„ν•΄ ꡬ쑰체의 νƒ€μž…μœΌλ‘œ μ‚¬μš©λœλ‹€.

νƒ€μž… λ§€κ°œλ³€μˆ˜λŠ” ꡬ쑰체의 각 μΈμŠ€ν„΄μŠ€μ— λŒ€ν•΄ νƒ€μž… 인수라고 ν•˜λŠ” μ„œλ‘œ λ‹€λ₯Έ νƒ€μž…μ„ ν•¨κ»˜ μ œκ³΅ν•  수 μžˆμ§€λ§Œ νƒ€μž… μΈμˆ˜κ°€ 제곡된 μΈμŠ€ν„΄μŠ€ λ‚΄μ—μ„œλŠ” 일관성을 μœ μ§€ν•œλ‹€.

νƒ€μž… λ§€κ°œλ³€μˆ˜λŠ” μ „ν˜•μ μœΌλ‘œ T λ‚˜ U 같은 단일 문자 이름 λ˜λŠ” Key Value 같은 파슀칼 μΌ€μ΄μŠ€ 이름을 κ°–λŠ”λ‹€.

10.1 μ œλ„€λ¦­ ν•¨μˆ˜

λ§€κ°œλ³€μˆ˜ κ΄„ν˜Έ λ°”λ‘œ μ•ž ν™€ν™”μ‚΄κ΄„ν˜Έ(<, >) 둜 묢인 νƒ€μž… λ§€κ°œλ³€μˆ˜μ— 별칭을 λ°°μΉ˜ν•΄ ν•¨μˆ˜λ₯Ό μ œλ„€λ¦­μœΌλ‘œ λ§Œλ“ λ‹€.

그러면 ν•΄λ‹Ή νƒ€μž… λ§€κ°œλ³€μˆ˜λ₯Ό ν•¨μˆ˜μ˜ λ³Έλ¬Έ λ‚΄λΆ€μ˜ λ§€κ°œλ³€μˆ˜ νƒ€μž… μ• λ„ˆν…Œμ΄μ…˜, λ°˜ν™˜ νƒ€μž… μ• λ„ˆν…Œμ΄μ…˜, νƒ€μž… μ• λ„ˆν…Œμ΄μ…˜μ— μ‚¬μš©ν•  수 μžˆλ‹€.

function identity<T>(input: T) {
  return input;
}

const numberic = identity("me"); // νƒ€μž… : me;
const stringy = identity(123); // νƒ€μž… : 123;
const identity = <T>(input: T) => input;
identity(123); // νƒ€μž… :123

10.1.2 닀쀑 ν•¨μˆ˜ νƒ€μž… λ§€κ°œλ³€μˆ˜

μž„μ˜μ˜ 수의 νƒ€μž… λ§€κ°œλ³€μˆ˜λ₯Ό μ‰Όν‘œλ‘œ ꡬ뢄해 ν•¨μˆ˜λ₯Ό μ •μ˜ν•œλ‹€. μ œλ„€λ¦­ ν•¨μˆ˜μ˜ 각 ν˜ΈμΆœμ€ 각 νƒ€μž… λ§€κ°œλ³€μˆ˜μ— λŒ€ν•œ 자체 κ°’ 집합을 확인할 수 μžˆλ‹€.

ν•¨μˆ˜κ°€ μ—¬λŸ¬ 개의 νƒ€μž… λ§€κ°œλ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λ©΄ ν•΄λ‹Ή ν•¨μˆ˜μ— λŒ€ν•œ ν˜ΈμΆœμ€ λͺ…μ‹œμ μœΌλ‘œ μ œλ„€λ¦­ νƒ€μž…μ„ λͺ¨λ‘ μ„ μ–Έν•˜μ§€ μ•Šκ±°λ‚˜ λͺ¨λ‘ μ„ μ–Έν•΄μ•Ό ν•œλ‹€.

function makeTuple<First, Second>(fist: First, second: Second) {
  return [fist, second] as const;
}

10.2 μ œλ„€λ¦­ μΈν„°νŽ˜μ΄μŠ€

μΈν„°νŽ˜μ΄μŠ€λ„ μ œλ„€λ¦­μœΌλ‘œ μ„ μ–Έν•  수 μžˆλ‹€. μΈν„°νŽ˜μ΄μŠ€λŠ” ν•¨μˆ˜μ™€ μœ μ‚¬ν•œ μ œλ„€λ¦­ κ·œμΉ™μ„ λ”°λ₯΄λ©° μΈν„°νŽ˜μ΄μŠ€ 이름 λ’€ <κ³Ό > 사이에 μ„ μ–Έλœ μž„μ˜μ˜ 수의 νƒ€μž… λ§€κ°œλ³€μˆ˜λ₯Ό κ°–λŠ”λ‹€.

interface Box<T> {
  inside: T;
};

let stringBox: Box<string> = {
  inside: 'abc',
}

let numberBox: Box<number> = {
  inside: 1111,
}

μž¬λ°ŒλŠ” 사싀은 νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œ λ‚΄μž₯ Array λ©”μ„œλ“œλŠ” μ œλ„€λ¦­ μΈν„°νŽ˜μ΄μŠ€λ‘œ μ •μ˜λœλ‹€λŠ” 점이닀.

10.2.1 μœ μΆ”λœ μ œλ„€λ¦­ μΈν„°νŽ˜μ΄μŠ€ νƒ€μž…

μ œλ„€λ¦­ ν•¨μˆ˜μ™€ λ§ˆμ°¬κ°€μ§€λ‘œ μ œλ„€λ¦­ μΈν„°νŽ˜μ΄μŠ€μ˜ νƒ€μž… μΈμˆ˜λŠ” μ‚¬μš©λ²•μ—μ„œ μœ μΆ”ν•  수 μžˆλ‹€.

interface LinkedNode<Value> {
  next?: LinkedNode<Value>;
  value: Value;
}

function getLast<Value>(node: LinkedNode<Value>): Value {
  return node.next ? getLast(node.next) : node.value;
}

// μœ μΆ”λœ Value νƒ€μž…: Date
let lastDate = getLast({
  value: new Date("09-13-1993");
});

10.3 μ œλ„€λ¦­ 클래슀

μΈν„°νŽ˜μ΄μŠ€ 처럼 ν΄λž˜μŠ€λ„ λ‚˜μ€‘μ— λ©€λ²„μ—μ„œ μ‚¬μš©ν•  μž„μ˜μ˜ 수의 νƒ€μž… λ§€κ°œλ³€μˆ˜λ₯Ό μ„ μ–Έν•  수 μžˆλ‹€. 클래슀의 각 μΈμŠ€ν„΄μŠ€λŠ” νƒ€μž… λ§€κ°œλ³€μˆ˜λ‘œ 각자 λ‹€λ₯Έ νƒ€μž… 인수 집합을 κ°€μ§„λ‹€.

class Secret<Key, Value> {
  key: Key;
  value: Value;

  constructor(key: Key, value: Value) {
    this.key = key;
    this.value = value;
  }
  
  getValue(key: Key): Value | undefined {
    return this.key === key ? this.value : undefined;
  }
}

10.3.1 λͺ…μ‹œμ  μ œλ„€λ¦­ 클래슀 νƒ€μž…

μ œλ„€λ¦­ 클래슀 μΈμŠ€ν„΄μŠ€ν™”λŠ” μ œλ„€λ¦­ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” 것과 λ™μΌν•œ νƒ€μž… 인수 μœ μΆ” κ·œμΉ™μ„ λ”°λ₯Έλ‹€.

ν•¨μˆ˜ μƒμ„±μžμ— μ „λ‹¬λœ λ§€κ°œλ³€μˆ˜μ˜ νƒ€μž…μœΌλ‘œλΆ€ν„° νƒ€μž… 인수λ₯Ό μœ μΆ”λ₯Ό ν•  수 μžˆλ‹€λ©΄ μœ μΆ”λœ νƒ€μž…μ„ μ‚¬μš©ν•œλ‹€.

ν•˜μ§€λ§Œ μƒμ„±μžμ— μ „λ‹¬λœ μΈμˆ˜μ—μ„œ 클래슀 νƒ€μž… 인수λ₯Ό μœ μΆ”ν•  수 μ—†λŠ” κ²½μš°μ—λŠ” νƒ€μž… 인수의 기본값은 unknown 이 λœλ‹€.

class CurriedCallback<Input> {
  #callback: (input: Input) => void;

  constructor(callback: (input: Input) => void) {
    this.#callback = (input: Input) => {
      console.log(input);
      callback(input);
    }
  }
  
  call(input: Input) {
    this.#callback(input);
  }
}

new CurriedCallback((input: string) => {
  console.log(input.length);
});

new CurriedCallback((input) => {
  console.log(input.length); // Error length does not exist on type unknown
})

10.3.3 μ œλ„€λ¦­ μΈν„°νŽ˜μ΄μŠ€ κ΅¬ν˜„

μ œλ„€λ¦­ ν΄λž˜μŠ€λŠ” λͺ¨λ“  ν•„μš”ν•œ λ§€κ°œλ³€μˆ˜λ₯Ό μ œκ³΅ν•¨μœΌλ‘œμ¨ μ œλ„€λ¦­ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œλ‹€.

interface ActingCredit<Role> {
  role: Role;
};

class MoviePart implements ActingCredit<string> {
  role: string;
  speaking: boolean;

  constructor(role: string, speaking: boolean) {
    this.role = role;
    this.speaking = speaking;
  }
}

class IncorrectExtension implements ActingCredit<string> {
  role: boolean;
  // Error role in type IncorrectExtension
}

10.3.4 λ©”μ„œλ“œ μ œλ„€λ¦­

클래슀 λ©”μ„œλ“œλŠ” 클래슀 μΈμŠ€ν„΄μŠ€μ™€ λ³„κ°œλ‘œ 자체 μ œλ„€λ¦­ νƒ€μž…μ„ μ„ μ–Έ κ°€λŠ₯ν•˜λ‹€. μ œλ„€λ¦­ λ©”μ„œλ“œμ˜ λŒ€ν•œ 각각의 ν˜ΈμΆœμ€ 각 νƒ€μž… λ§€κ°œλ³€μˆ˜μ— λŒ€ν•΄ λ‹€λ₯Έ νƒ€μž… 인수λ₯Ό κ°–λŠ”λ‹€.

class CreatePairFactor<Key> {
  key: Key;

  constructor(key: Key) {
    this.key = key;
  }
  
  createPair<Value>(value: Value) {
    return { key: this.key, value };
  }
};

// νƒ€μž… : CreatePairFactor<string>
const factory = new CreatePairFactor("role");

// νƒ€μž… : { key: string, value: number }
const numberPair = factory.createPair(10);

// νƒ€μž… : { key: string, value: string }
const stringPair = factory.createPair(10);

10.3.5 정적 클래슀 μ œλ„€λ¦­

클래슀의 정적 λ©€λ²„λŠ” μΈμŠ€ν„΄μŠ€ 멀버와 κ΅¬λ³„λ˜κ³  클래슀의 νŠΉμ • μΈμŠ€ν„΄μŠ€μ™€ μ—°κ²°λ˜μ–΄ μžˆμ§€ μ•Šλ‹€. 클래슀의 정적 λ©€λ²„λŠ” 클래슀 μΈμŠ€ν„΄μŠ€μ— μ ‘κ·Όν•  수 μ—†κ±°λ‚˜ νƒ€μž… 정보λ₯Ό μ§€μ •ν•  수 μ—†λ‹€.

정적 클래슀 λ©”μ„œλ“œλŠ” νƒ€μž… λ§€κ°œλ³€μˆ˜λ₯Ό μ„ μ–Έν•  수 μžˆμ§€λ§Œ ν΄λž˜μŠ€μ— μ„ μ–Έλœ μ–΄λ–€ νƒ€μž… λ§€κ°œλ³€μˆ˜μ—λ„ μ ‘κ·Όν•  수 μ—†λ‹€.

class BothLogger<OnInstance> {
  instanceLog(value: OnInstance) {
    console.log(value);
    return value;
  }
  
  static staticLog<OnStatic>(value: OnStatic) {
    let fromInstacne: OnStatic; // Error Static member cannot reference class type aruments
  }
}

10.4 μ œλ„€λ¦­ νƒ€μž… 별칭

νƒ€μž… 인수λ₯Ό μ‚¬μš©ν•΄ μ œλ„€λ¦­μ„ λ§Œλ“œλŠ” νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ λ§ˆμ§€λ§‰ κ΅¬μ‘°μ²΄λŠ” νƒ€μž… 별칭이닀. 각 νƒ€μž… λ³„μΉ­μ—λŠ” T λ₯Ό λ°›λŠ” Nullish νƒ€μž…κ³Ό 같은 μž„μ˜μ˜ 수의 νƒ€μž… λ§€κ°œλ³€μˆ˜κ°€ μ£Όμ–΄μ§„λ‹€.

type Nullish<T> = T | null | undefined;

10.4.1 μ œλ„€λ¦­ νŒλ³„λœ μœ λ‹ˆμ–Έ

νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ λ‚΄λ‘œμž‰μ„ μ•„λ¦„λ‹΅κ²Œ κ²°ν•©ν•΄μ£ΌλŠ” ν•„μžμ˜ κ°€μž₯ μ’‹μ•„ν•˜λŠ” νŒ¨ν„΄μ˜ κΈ°λŠ₯이닀.

type Result<Data> = FailureResult | SuccessfulResult<Data>;

interface FailureResult {
  error: Error;
  succeeded: false;
};

interface SuccessfulResult<Data> {
  data: Data;
  succeeded: true;
};

function handleresult(result: Result<string>) {
  if (result.succeeded) {
    console.log(result.data);
  } else if (!result.succeeded) {
    console.log(result.error)
  }
}

10.5 μ œλ„€λ¦­ μ œν•œμž

νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” μ œλ„€λ¦­ νƒ€μž… λ§€κ°œλ³€μˆ˜μ˜ λ™μž‘μ„ μˆ˜μ •ν•˜λŠ” ꡬ문도 μ œκ³΅ν•œλ‹€.

10.5.1 μ œλ„€λ¦­ κΈ°λ³Έκ°’

μ§€κΈˆκΉŒμ§€ μ œλ„€λ¦­ νƒ€μž…μ΄ νƒ€μž… μ• λ„ˆν…Œμ΄μ…˜μ— μ‚¬μš©λ˜κ±°λ‚˜ extends λ˜λŠ” implements 의 κΈ°λ³Έ 클래슀둜 μ‚¬μš©λ˜λŠ” 경우 각 νƒ€μž… λ§€κ°œλ³€μˆ˜μ— λŒ€ν•œ νƒ€μž… 인수λ₯Ό μ œκ³΅ν•΄μ•Ό ν•œλ‹€.

νƒ€μž… λ§€κ°œλ³€μˆ˜ μ„ μ–Έ 뒀에 = 와 κΈ°λ³Έ νƒ€μž…μ„ λ°°μΉ˜ν•΄ νƒ€μž… 인수λ₯Ό λͺ…μ‹œμ μœΌλ‘œ μ œκ³΅ν•  수 μžˆλ‹€. 기본값은 νƒ€μž… μΈμˆ˜κ°€ λͺ…μ‹œμ μœΌλ‘œ μ„ μ–Έλ˜μ§€ μ•Šκ³  μœ μΆ”ν•  수 μ—†λŠ” λͺ¨λ“  후속 νƒ€μž…μ— μ‚¬μš©λœλ‹€.

interface Quote<T = string> {
  value: T;
}

let explicit: Quote<number> = { value: 123 };

νƒ€μž… λ§€κ°œλ³€μˆ˜λŠ” λ™μΌν•œ μ„ μ–Έ μ•ˆμ˜ μ•žμ„  νƒ€μž… λ§€κ°œλ³€μˆ˜λ₯Ό κΈ°λ³Έκ°’μœΌλ‘œ κ°€μ§ˆ 수 μžˆλ‹€. 각 νƒ€μž… λ§€κ°œλ³€μˆ˜λŠ” 선언에 λŒ€ν•œ μƒˆλ‘œμš΄ νƒ€μž…μ„ λ„μž…ν•˜λ―€λ‘œ ν•΄λ‹Ή μ„ μ–Έ μ΄ν›„μ˜ νƒ€μž… λ§€κ°œλ³€μˆ˜μ— λŒ€ν•œ κΈ°λ³Έκ°’μœΌλ‘œ 이λ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.

λͺ¨λ“  κΈ°λ³Έ νƒ€μž… λ§€κ°œλ³€μˆ˜λŠ” κΈ°λ³Έ ν•¨μˆ˜ λ§€κ°œλ³€μˆ˜μ² λ¨Έ μ„ μ–Έ λͺ©λ‘μ˜ 제일 λ§ˆμ§€λ§‰μ— 와야 ν•œλ‹€.

// Error Required type parameters may not follow optional type parameters
function inTheMiddle<First, Second = boolean, Third = number, Fourth>() {}

10.6 μ œν•œλœ μ œλ„€λ¦­ νƒ€μž…

기본적으둜 μ œλ„€λ¦­ νƒ€μž…μ—λŠ” 클래슀 μΈν„°νŽ˜μ΄μŠ€ 원싯값 μœ λ‹ˆμ–Έ 별칭 λ“± λͺ¨λ“  νƒ€μž…μ„ μ œκ³΅ν•  수 μžˆλ‹€. κ·ΈλŸ¬λ‚˜ 일뢀 ν•¨μˆ˜λŠ” μ œν•œλœ νƒ€μž…μ—μ„œλ§Œ μž‘λ™ν•΄μ•Ό ν•œλ‹€.

νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” νƒ€μž… λ§€κ°œλ³€μˆ˜κ°€ νƒ€μž…μ„ ν™•μž₯ν•΄μ•Ό ν•œλ‹€κ³  μ„ μ–Έν•  수 있으며 별칭 νƒ€μž…μ—λ§Œ ν—ˆμš©λ˜λŠ” μž‘μ—…μ΄λ‹€. νƒ€μž… λ§€κ°œλ³€μˆ˜λ₯Ό μ œν•œν•˜λŠ” ꡬ문은 λ§€κ°œλ³€μˆ˜ 이름 뒀에 extends ν‚€μ›Œλ“œλ₯Ό λ°°μΉ˜ν•˜κ³  κ·Έ 뒀에 이λ₯Ό μ œν•œν•  νƒ€μž…μ„ λ°°μΉ˜ν•œλ‹€.

μ œλ„€λ¦­ ν•¨μˆ˜κ°€ T μ œλ„€λ¦­μ— λŒ€ν•œ length λ₯Ό κ°€μ§„ λͺ¨λ“  νƒ€μž…μ„ 받아듀이도둝 κ΅¬ν˜„ν•œ μ½”λ“œμ΄λ‹€. λ¬Έμžμ—΄ λ°°μ—΄ length: number λ₯Ό κ°€μ§„ κ°μ²΄λŠ” ν—ˆμš©λ˜μ§€λ§Œ Date 와 같은 νƒ€μž… ν˜•νƒœμ—λŠ” μˆ«μžν˜• length 멀버가 μ—†μœΌλ―€λ‘œ νƒ€μž… 였λ₯˜κ°€ λ°œμƒν•œλ‹€.

interface WithLength {
  length: number;
}

function logWithLength<T extends WithLength>(input: T) {
  console.log(`Length: ${input.length}`);
  return input;
}

logWithLength('string'); // νƒ€μž… string
logWithLength([false, true]); // boolean[]
logWithLength({ length: 123 }); // {length: number}

logWithLength(new Date()); // Error Date is not assignable to parameter of type WithLength

10.6.1 keyof 와 μ œν•œλœ νƒ€μž… λ§€κ°œλ³€μˆ˜

extends 와 keyof λ₯Ό ν•¨κ»˜ μ‚¬μš©ν•˜λ©΄ νƒ€μž… λ§€κ°œλ³€μˆ˜μ˜ ν‚€λ‘œ μ œν•œν•  수 μžˆλ‹€. λ˜ν•œ μ œλ„€λ¦­ νƒ€μž…μ˜ ν‚€λ₯Ό κ±±μ •ν•˜λŠ” μœ μΌν•œ 방법이기도 ν•˜λ‹€.

function get<T, Key extends keyof T>(container: T, key: Key) {
  return container[key];
}

const role = {
  favorite: "a",
  others: ["b", "c", "d"],
}

const favorite = get(role, 'favorite'); // νƒ€μž… string;
const others = get(role, 'others'); // νƒ€μž… string[];

const missing = get(role, 'extras'); // Error

keyof κ°€ μ—†μ—ˆλ”λΌλ©΄ μ œλ„€λ¦­ key λ§€κ°œλ³€μˆ˜λ₯Ό μ˜¬λ°”λ₯΄κ²Œ μž…λ ₯ν•  방법이 μ—†μ—ˆμ„ 것이닀.

T만 제곡되고 key λ§€κ°œλ³€μˆ˜κ°€ λͺ¨λ“  keyof T 일 수 μžˆλŠ” 경우라면 λ°˜ν™˜ νƒ€μž…μ€ Container 에 μžˆλŠ” λͺ¨λ“  속성 값에 λŒ€ν•œ μœ λ‹ˆμ–Έ νƒ€μž…μ΄ λœλ‹€.

μ΄λ ‡κ²Œ ꡬ체적이지 μ•Šμ€ ν•¨μˆ˜ 선언은 각 호좜이 νƒ€μž… 인수λ₯Ό 톡해 νŠΉμ • key λ₯Ό κ°€μ§ˆ 수 μžˆμŒμ„ νƒ€μž…μŠ€ν¬λ¦½νŠΈμ— λ‚˜νƒ€λ‚Ό 수 μ—†λ‹€.

function get<T>(container: T, key: keyof T) {
  return container[key];
}

const role = {
  favorite: "a",
  others: ["b", "c", "d"],
}

const found = get(role, 'favorite'); // νƒ€μž… string | string[]

10.8 μ œλ„€λ¦­ μ˜¬λ°”λ₯΄κ²Œ μ‚¬μš©ν•˜κΈ°

νƒ€μž…μŠ€ν¬λ¦½νŠΈλ₯Ό 처음 μ ‘ν•œ κ°œλ°œμžλŠ” μ΄λ”°κΈˆ μ œλ„€λ¦­μ„ κ³Όλ„ν•˜κ²Œ μ‚¬μš©ν•΄ 읽기 ν˜Όλž€μŠ€λŸ½κ³  μ§€λ‚˜μΉ˜κ²Œ λ³΅μž‘ν•œ μ½”λ“œλ₯Ό λ§Œλ“€κΈ°λ„ ν•œλ‹€.

νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ λͺ¨λ²• μ‚¬λ‘€λŠ” ν•„μš”ν•  λ•Œλ§Œ μ œλ„€λ¦­μ„ μ‚¬μš©ν•˜κ³  μ œλ„€λ¦­μ„ μ‚¬μš©ν•  λ•ŒλŠ” 무엇을 μœ„ν•΄ μ‚¬μš©ν•˜λŠμ§€ λͺ…ν™•ν•΄μ•Ό ν•œλ‹€.

10.8.1 μ œλ„€λ¦­ ν™©κΈˆλ₯ 

ν•¨μˆ˜μ— νƒ€μž… λ§€κ°œλ³€μˆ˜κ°€ ν•„μš”ν•œμ§€ μ—¬λΆ€λ₯Ό νŒλ‹¨ν•  수 μžˆλŠ” κ°„λ‹¨ν•˜κ³  λΉ λ₯Έ 방법은 νƒ€μž… λ§€κ°œλ³€μˆ˜κ°€ μ΅œμ†Œ 두 번 이상 μ‚¬μš©λ˜μ—ˆλŠ”μ§€ ν™•μΈν•˜λŠ” 것이닀.

function logIput<Input extends string>(input: Input) {
  console.log(`Hi`, input);
}

이런 ν•¨μˆ˜μ˜ Input νƒ€μž… λ§€κ°œλ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λŠ” 것은 λ³„λ‘œ μ“Έλͺ¨κ°€ μ—†λ‹€.

μ΄νŽ™ν‹°λΈŒ νƒ€μž…μŠ€ν¬λ¦½νŠΈ λŠ” μ œλ„€λ¦­ ν™©κΈˆλ₯ μ„ μ„€λͺ…ν•˜λ©° μ œλ„€λ¦­μœΌλ‘œ μž‘μ—…ν•  λ•Œ μœ μš©ν•˜κ³  ν›Œλ₯­ν•œ νŒλ„ μ†Œκ°œν•œλ‹€.

10.8.2 μ œλ„€λ¦­ λͺ…λͺ… κ·œμΉ™

νƒ€μž…μŠ€ν¬λ¦½ν‹€λ₯Ό ν¬ν•¨ν•œ λ§Žμ€ μ–Έμ–΄κ°€ μ§€ν‚€κ³  μžˆλŠ” νƒ€μž… λ§€κ°œλ³€μˆ˜μ— λŒ€ν•œ ν‘œμ€€ λͺ…λͺ… κ·œμΉ™μ€

기본적으둜 T λ₯Ό μ‚¬μš©ν•˜κ³  후속 νƒ€μž… λ§€κ°œλ³€μˆ˜κ°€ μ‘΄μž¬ν•˜λ©΄ U, V 등을 μ‚¬μš©ν•˜λŠ” 것이닀.

⚠️ **GitHub.com Fallback** ⚠️