ν‹°μŠ€ν† λ¦¬ λ·°

TypeScript

πŸ“˜ Type System

yunieyunie 2022. 12. 13. 21:19

πŸ•Ά μž‘μ„±μžμ™€ μ‚¬μš©μžμ˜ κ΄€μ μœΌλ‘œ μ½”λ“œ 바라보기

Type System

νƒ€μž… μ‹œμŠ€ν…œμ—λŠ” λ‹€μŒκ³Ό 같은 두 κ°€μ§€μ˜ μ‹œμŠ€ν…œμ΄ μžˆλ‹€.

  1. μ»΄νŒŒμΌλŸ¬μ—κ²Œ μ‚¬μš©ν•˜λŠ” νƒ€μž…μ„ λͺ…μ‹œμ μœΌλ‘œ μ§€μ •
  2. μ»΄νŒŒμΌλŸ¬κ°€ μžλ™μœΌλ‘œ νƒ€μž…μ„ μΆ”λ‘ 

TypeScript와 JavaScript의 Type System

νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” 두 κ°€μ§€ μ‹œμŠ€ν…œ λͺ¨λ‘ κ°€λŠ₯ν•œλ° 기본적으둜 νƒ€μž…μ„ λͺ…μ‹œμ μœΌλ‘œ μ§€μ •ν•  수 있고 μ§€μ •ν•˜μ§€ μ•ŠμœΌλ©΄ νƒ€μž…μŠ€ν¬λ¦½νŠΈ μ»΄νŒŒμΌλŸ¬κ°€ μžλ™μœΌλ‘œ νƒ€μž…μ„ μΆ”λ‘ ν•œλ‹€.
νƒ€μž…μ€ ν•΄λ‹Ή λ³€μˆ˜κ°€ ν•  수 μžˆλŠ” 일을 κ²°μ •ν•˜λŠ”λ° μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” ν•¨μˆ˜ μ‚¬μš©λ²•μ— λŒ€ν•œ μ˜€ν•΄λ₯Ό μ•ΌκΈ°ν•œλ‹€.
예λ₯Ό λ“€μ–΄ μ–΄λ–€ ν•¨μˆ˜ μ•ˆμ˜ λ§€κ°œλ³€μˆ˜κ°€ numberνƒ€μž…μ΄μ–΄μ•Ό ν•˜λŠ”λ° string을 μž…λ ₯ν•˜λ©΄ NaN으둜 좜λ ₯이 λœλ‹€.
즉, μ‚¬μš©μžμ—κ²Œ 였λ₯˜κ°€ μžˆλ‹€λŠ” 것을 μ•Œλ €μ£Όμ§€ μ•ŠλŠ”λ‹€.

// JavaScript
  // (f2 μ‹€ν–‰μ˜ κ²°κ³Όκ°€ NaN 을 μ˜λ„ν•œ 것이 μ•„λ‹ˆλΌλ©΄)
  // 이 ν•¨μˆ˜μ˜ μž‘μ„±μžλŠ” λ§€κ°œλ³€μˆ˜ a κ°€ number νƒ€μž…μ΄λΌλŠ” κ°€μ •μœΌλ‘œ ν•¨μˆ˜λ₯Ό μž‘μ„±ν–ˆμŠ΅λ‹ˆλ‹€. 
  function f2(a) {
  return a * 38; 
  }

  // μ‚¬μš©μžλŠ” μ‚¬μš©λ²•μ„ μˆ™μ§€ν•˜μ§€ μ•Šμ€ 채, λ¬Έμžμ—΄μ„ μ‚¬μš©ν•˜μ—¬ ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν–ˆμŠ΅λ‹ˆλ‹€. 
  console.log(f2(10)); // 380
  console.log(f2('Mark')); // NaN

TypeScript의 μΆ”λ‘ 

νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” νƒ€μž…μ΄ λͺ…μ‹œμ μœΌλ‘œ μ§€μ •λ˜μ§€ μ•ŠμœΌλ©΄ 좔둠을 ν•˜κ²Œ λœλ‹€.
예λ₯Ό λ“€μ–΄ μ–΄λ–€ ν•¨μˆ˜ μ•ˆμ˜ λ§€κ°œλ³€μˆ˜μ˜ νƒ€μž…μ΄ μ§€μ •λ˜μ§€ μ•Šμ•˜λ‹€λ©΄ any둜 μΆ”λ‘ ν•œλ‹€.

// νƒ€μž…μŠ€ν¬λ¦½νŠΈ μ½”λ“œμ§€λ§Œ,
  // a 의 νƒ€μž…μ„ λͺ…μ‹œμ μœΌλ‘œ μ§€μ •ν•˜μ§€ μ•Šμ€ κ²½μš°μ΄κ°€ λ•Œλ¬Έμ— a λŠ” any 둜 μΆ”λ‘ λ©λ‹ˆλ‹€. 
  // ν•¨μˆ˜μ˜ 리턴 νƒ€μž…μ€ number 둜 μΆ”λ‘ λ©λ‹ˆλ‹€. (NaN 도 number 의 ν•˜λ‚˜μž…λ‹ˆλ‹€.)
  function f3(a) { 
  return a * 38;
  }

  // μ‚¬μš©μžλŠ” a κ°€ any 이기 λ•Œλ¬Έμ—, μ‚¬μš©λ²•μ— 맞게 λ¬Έμžμ—΄μ„ μ‚¬μš©ν•˜μ—¬ ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν–ˆμŠ΅λ‹ˆλ‹€. 
  console.log(f3(10)); // 380
  console.log(f3('Mark') + 5); // NaN

nolmplicitAny

ν•˜μ§€λ§Œ μ΄λŠ” μœ„ν—˜ν•œ μš”μ†Œκ°€ 될 수 있으며 이λ₯Ό λ°©μ§€ν•˜κΈ° μœ„ν•œ μ˜΅μ…˜ nolmplicitAny이 μžˆλ‹€.
νƒ€μž…μ„ λͺ…μ‹œν•˜μ§€ μ•Šμ€ 경우 νƒ€μž…μŠ€ν¬λ¦½νŠΈκ°€ any라고 μΆ”λ‘ ν•˜κ²Œ 되면 컴파일 μ—λŸ¬λ₯Ό λ°œμƒμ‹œμΌœ νƒ€μž…μ„ μ§€μ •ν•˜λ„λ‘ μœ λ„ν•˜λŠ” μ˜΅μ…˜μ΄λ‹€.
νƒ€μž…μ„ λͺ…μ‹œν•΄μ£Όμ§€ μ•ŠμœΌλ©΄ error TS7006: parameter 'a' implicitly has an 'any' type μ΄λΌλŠ” μ—λŸ¬κ°€ λœ¬λ‹€.
즉, μž‘μ„±μžκ°€ νƒ€μž…μ„ 지정해쀄 기회λ₯Ό λΆ€μ—¬ν•΄ μ‚¬μš©μžμ—κ²Œ μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•Šλ„λ‘ ν•œλ‹€.

// error TS7006: Parameter 'a' implicitly has an 'any' type. 
  function f3(a) {
  return a * 38; 
  }

  // μ‚¬μš©μžμ˜ μ½”λ“œλ₯Ό μ‹€ν–‰ν•  수 μ—†μŠ΅λ‹ˆλ‹€. 컴파일이 μ •μƒμ μœΌλ‘œ 마무리 될 수 μžˆλ„λ‘ μˆ˜μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€.
  console.log(f3(10)); 
  console.log(f3('Mark') + 5);

number둜 μΆ”λ‘ λœ return νƒ€μž…

// λ§€κ°œλ³€μˆ˜μ˜ νƒ€μž…μ€ λͺ…μ‹œμ μœΌλ‘œ μ§€μ •ν–ˆμŠ΅λ‹ˆλ‹€.
  // λͺ…μ‹œμ μœΌλ‘œ μ§€μ •ν•˜μ§€ μ•Šμ€ ν•¨μˆ˜μ˜ 리턴 νƒ€μž…μ€ number 둜 μΆ”λ‘ λ©λ‹ˆλ‹€. 
  function f4(a: number) {
  if (a > 0) { 
  return a * 38;
    } 
  }

  // μ‚¬μš©μžλŠ” μ‚¬μš©λ²•μ— 맞게 μˆ«μžν˜•μ„ μ‚¬μš©ν•˜μ—¬ ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν–ˆμŠ΅λ‹ˆλ‹€.
  // ν•΄λ‹Ή ν•¨μˆ˜μ˜ 리턴 νƒ€μž…μ€ number 이기 λ•Œλ¬Έμ—, νƒ€μž…μ— λ”°λ₯΄λ©΄ 이어진 연산을 λ°”λ‘œ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 
  // ν•˜μ§€λ§Œ μ‹€μ œ undefined + 5 κ°€ μ‹€ν–‰λ˜μ–΄ NaN 이 좜λ ₯λ©λ‹ˆλ‹€.
  console.log(f4(5)); // 190 
  console.log(f4(-5) + 5); // NaN

μœ„μ˜ μ½”λ“œμ—μ„œ 리턴 νƒ€μž…μ΄ μ§€μ •λ˜μ§€ μ•Šμ•˜κ³  f4(-5)λŠ” undefined인데 νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„  number둜 좔둠을 ν•œλ‹€.
이λ₯Ό 톡해 기본적으둜 numberμ•ˆμ— undefinedκ°€ ν¬ν•¨λ˜μ–΄ μžˆμŒμ„ μ•Œ 수 μžˆλ‹€.

strictNullChecks

λ”°λΌμ„œ strictNullChecks μ˜΅μ…˜μ„ μΌœμ„œ λͺ¨λ“  νƒ€μž…μ— μžλ™μœΌλ‘œ ν¬ν•¨λ˜μ–΄ μžˆλŠ” nullκ³Ό undefinedλ₯Ό μ œκ±°ν•  수 μžˆλ‹€.
이 μ˜΅μ…˜μ„ 켜면 λ‹€μŒκ³Ό 같이 f4(-5)λΆ€λΆ„μ—μ„œ μ—λŸ¬κ°€ λ‚œλ‹€.

// λ§€κ°œλ³€μˆ˜μ˜ νƒ€μž…μ€ λͺ…μ‹œμ μœΌλ‘œ μ§€μ •ν–ˆμŠ΅λ‹ˆλ‹€.
  // λͺ…μ‹œμ μœΌλ‘œ μ§€μ •ν•˜μ§€ μ•Šμ€ ν•¨μˆ˜μ˜ 리턴 νƒ€μž…μ€ number | undefined 둜 μΆ”λ‘ λ©λ‹ˆλ‹€. 
  function f4(a: number) {
  if (a > 0) { 
  return a * 38;
    } 
  }

  // μ‚¬μš©μžλŠ” μ‚¬μš©λ²•μ— 맞게 μˆ«μžν˜•μ„ μ‚¬μš©ν•˜μ—¬ ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν–ˆμŠ΅λ‹ˆλ‹€. 
  // ν•΄λ‹Ή ν•¨μˆ˜μ˜ 리턴 νƒ€μž…μ€ number | undefined 이기 λ•Œλ¬Έμ—, 
  // νƒ€μž…μ— λ”°λ₯΄λ©΄ 이어진 연산을 λ°”λ‘œ ν•  수 μ—†μŠ΅λ‹ˆλ‹€.
  // 컴파일 μ—λŸ¬λ₯Ό κ³ μ³μ•Όν•˜κΈ° ν•˜κΈ° λ•Œλ¬Έμ— μ‚¬μš©μžμ™€ μž‘μ„±μžκ°€ μ˜λ…Όμ„ ν•΄μ•Όν•©λ‹ˆλ‹€.
  console.log(f4(5));
  console.log(f4(-5) + 5); // error TS2532: Object is possibly 'undefined'

return νƒ€μž… μ§€μ •

// λ§€κ°œλ³€μˆ˜μ˜ νƒ€μž…κ³Ό ν•¨μˆ˜μ˜ 리턴 νƒ€μž…μ„ λͺ…μ‹œμ μœΌλ‘œ μ§€μ •ν–ˆμŠ΅λ‹ˆλ‹€.
  // μ‹€μ œ ν•¨μˆ˜ κ΅¬ν˜„λΆ€μ˜ 리턴 νƒ€μž…κ³Ό λͺ…μ‹œμ μœΌλ‘œ μ§€μ •ν•œ νƒ€μž…μ΄ μΌμΉ˜ν•˜μ§€ μ•Šμ•„ 컴파일 μ—λŸ¬κ°€ λ°œμƒν•©λ‹ˆλ‹€.
  // error TS2366: Function lacks ending return statement and return type does not incl 
  function f5(a: number): number {
  if (a > 0) { 
  return a * 38;
    } 
  }

noImplicitReturns

noImplicitReturns μ˜΅μ…˜μ€ ν•¨μˆ˜ λ‚΄μ—μ„œ λͺ¨λ“  μ½”λ“œκ°€ 값을 λ¦¬ν„΄ν•˜μ§€ μ•ŠμœΌλ©΄ 컴파일 μ—λŸ¬λ₯Ό λ°œμƒμ‹œν‚¨λ‹€.

// if κ°€ μ•„λ‹Œ 경우 return 을 직접 ν•˜μ§€ μ•Šκ³  μ½”λ“œκ°€ μ’…λ£Œλœλ‹€. 
  // error TS7030: Not all code paths return a value.
  function f5(a: number) { 
  if (a > 0) {
  return a * 38; 
    }
  }

λ§€κ°œλ³€μˆ˜μ— object κ°€ λ“€μ–΄μ˜€λŠ” 경우

// JavaScript 
  function f6(a) {
  return `이름은 ${a.name} 이고, μ—°λ ΉλŒ€λŠ” ${ 
  Math.floor(a.age / 10) * 10
    }λŒ€ μž…λ‹ˆλ‹€.`; 
  }

  console.log(f6({ name: 'Mark', age: 38 })); // 이름은 Mark 이고, μ—°λ ΉλŒ€λŠ” 30λŒ€ μž…λ‹ˆλ‹€. 
  console.log(f6('Mark')); // 이름은 undefined 이고, μ—°λ ΉλŒ€λŠ” NaNλŒ€ μž…λ‹ˆλ‹€.

μœ„μ˜ μ½”λ“œλ₯Ό λ‹€μŒκ³Ό 같이 object literal type으둜 λ°”κΏ”μ£Όλ©΄ λ˜κ² λ‹€.

function f7(a: { name: string; age: number }): string { 
  return `이름은 ${a.name} 이고, μ—°λ ΉλŒ€λŠ” ${
  Math.floor(a.age / 10) * 10 
    }λŒ€ μž…λ‹ˆλ‹€.`;
  }

  console.log(f7({ name: 'Mark', age: 38 })); // 이름은 Mark 이고, μ—°λ ΉλŒ€λŠ” 30λŒ€ μž…λ‹ˆλ‹€. 
  console.log(f7('Mark')); // error TS2345: Argument of type 'string' is not 
  assignable to parameter of type '{ name: string; age: number; }'.

ν•˜μ§€λ§Œ 맀번 길게 object literal type으둜 μ“°κΈ° νž˜λ“€κΈ°μ— νŠΉμ •ν•œ νƒ€μž…μœΌλ‘œ λ½‘μ•„μ„œ λ§Œλ“€μ–΄ λ†“λŠ” 방식을 μ“°μž.

interface PersonInterface { 
    name: string;
    age: number; 
  }

  type PersonTypeAlias = { 
    name: string;
    age: number; 
  };

  function f8(a: PersonInterface): string { 
  return `이름은 ${a.name} 이고, μ—°λ ΉλŒ€λŠ” ${
  Math.floor(a.age / 10) * 10 
    }λŒ€ μž…λ‹ˆλ‹€.`;
  }

  console.log(f8({ name: 'Mark', age: 38 })); // 이름은 Mark 이고, μ—°λ ΉλŒ€λŠ” 30λŒ€ μž…λ‹ˆλ‹€. 
  console.log(f8('Mark')); // error TS2345: Argument of type 'string' is not assignable to parameter of type 'PersonInterface'.

πŸ’» Structural Type System vs Nominal Type System

structural type system

ꡬ쑰가 κ°™μœΌλ©΄, 같은 νƒ€μž…μœΌλ‘œ μ·¨κΈ‰ν•˜λŠ” 방식이닀.

interface IPerson { 
    name: string; 
    age: number;
    speak(): string; 
  }

  type PersonType = { 
    name: string; 
    age: number;
    speak(): string; 
  };

  let personInterface: IPerson = {} as any; 
  let personType: PersonType = {} as any;
  personInterface = personType; 
  personType = personInterface;

IPersonκ³Ό PersonType이 λ˜‘κ°™μ€ ꡬ쑰λ₯Ό κ°€μ§€κ³  μžˆκΈ°μ— μ„œλ‘œμ—κ²Œ λŒ€μž…ν•΄λ„ λ¬Έμ œκ°€ μ—†λŠ” 것이닀.
보톡 νŠΉμ • νƒ€μž…μ„ λ§Œλ“€κ³  λ‹€λ₯Έ νƒ€μž…μ— 넣을 수 μžˆλŠ”λ° ꡳ이 νƒ€μž…μ„ λͺ…μ‹œν•˜μ§€ μ•Šμ•„λ„ ꡬ쑰만 κ°™μœΌλ©΄ 되기 λ•Œλ¬Έμ— 일일이 νƒ€μž…μ„ λ§Œλ“€μ§€ μ•Šμ•„λ„ λ˜λŠ” 것이닀.

nominal type system

ꡬ쑰가 같아도 이름이 λ‹€λ₯΄λ©΄, λ‹€λ₯Έ νƒ€μž…μœΌλ‘œ μ·¨κΈ‰ν•˜λŠ” 방식이닀.

type PersonID = string & { readonly brand: unique symbol }; 
  function PersonID(id: string): PersonID {
  return id as PersonID; 
  }

  function getPersonById(id: PersonID) {} 
  getPersonById(PersonID('id-aaaaaa'));
  getPersonById('id-aaaaaa'); // error TS2345: Argument of type 'string' is not assignable to parameter of type 'PersonID'. 
  Type 'string' is not assignable to type '{ readonly brand: unique symbol; }'.

μœ„μ˜ μ½”λ“œμ—μ„œ 보면 무쑰건 PersonID둜 μΉ˜ν™˜λœ ν˜•μ‹λ§Œ λ„£μ–΄μ•Ό ν•œλ‹€λŠ” 것이닀.
ν•˜μ§€λ§Œ 이 방식은 잘 μ‚¬μš©λ˜μ§€ μ•Šκ³  νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” λ”°λ₯΄μ§€ μ•ŠλŠ” 방식이닀.

duck typing

λ§Œμ•½ μ–΄λ–€ μƒˆκ°€ 였리처럼 κ±·κ³ , ν—€μ—„μΉ˜κ³ , κ½₯κ½₯κ±°λ¦¬λŠ” μ†Œλ¦¬λ₯Ό λ‚Έλ‹€λ©΄ λ‚˜λŠ” κ·Έ μƒˆλ₯Ό 였리라고 λΆ€λ₯Ό 것이닀. λΌλŠ” λœ»μ΄λ‹€.
λŒ€ν‘œμ μœΌλ‘œ νŒŒμ΄μ¬μ—μ„œ μ‚¬μš©ν•˜λŠ” μ‹œμŠ€ν…œμœΌλ‘œ structural type systemκ³Ό λΉ„μŠ·ν•˜λ‹€κ³  λ³Ό 수 μžˆλ‹€.
ν•˜μ§€λ§Œ νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” μ‚¬μš©λ˜μ§€ μ•ŠλŠ”λ‹€.

class Duck:
      def sound(self): 
          print u"κ½₯κ½₯"

  class Dog:
      def sound(self): 
          print u"멍멍"

  def get_sound(animal): 
     animal.sound()

  def main():
     bird = Duck() 
     dog = Dog() 
     get_sound(bird) 
     get_sound(dog)

🎨 νƒ€μž… ν˜Έν™˜μ„± (Type Compatibility)

μ„œλΈŒνƒ€μž…

// sub1 νƒ€μž…μ€ sup1 νƒ€μž…μ˜ μ„œλΈŒ νƒ€μž…μ΄λ‹€. 
  let sub1: 1 = 1;
  let sup1: number = sub1;
  sub1 = sup1; // error! Type 'number' is not assignable to type '1'. 

  // sub2 νƒ€μž…μ€ sup2 νƒ€μž…μ˜ μ„œλΈŒ νƒ€μž…μ΄λ‹€.
  let sub2: number[] = [1]; 
  let sup2: object = sub2;
  sub2 = sup2; // error! Type '{}' is missing the following properties from type 'number[]': length, pop, push, concat, and 16 more.

  // sub3 νƒ€μž…μ€ sup3 νƒ€μž…μ˜ μ„œλΈŒ νƒ€μž…μ΄λ‹€. 
  let sub3: [number, number] = [1, 2]; 
  let sup3: number[] = sub3;
  sub3 = sup3; // error! Type 'number[]' is not assignable to type '[number, number]'. Target requires 2 element(s) but source may have fewer.

  // sub4 νƒ€μž…μ€ sup4 νƒ€μž…μ˜ μ„œλΈŒ νƒ€μž…μ΄λ‹€. 
  let sub4: number = 1;
  let sup4: any = sub4; 
  sub4 = sup4;

  // sub5 νƒ€μž…μ€ sup5 νƒ€μž…μ˜ μ„œλΈŒ νƒ€μž…μ΄λ‹€. 
  let sub5: never = 0 as never;
  let sup5: number = sub5;
  sub5 = sup5; // error! Type 'number' is not assignable to type 'never'. 

  class Animal {}
  class Dog extends Animal { 
    eat() {}
  }

  // sub6 νƒ€μž…μ€ sup6 νƒ€μž…μ˜ μ„œλΈŒ νƒ€μž…μ΄λ‹€. 
  let sub6: Dog = new Dog();
  let sup6: Animal = sub6;
  sub6 = sup6; // error! Property 'eat' is missing in type 'SubAnimal' but required in type 'SubDog'.

μœ„μ˜ μ½”λ“œλ“€μ—μ„œ λ‹€μŒκ³Ό 같은 κ·œμΉ™λ“€μ„ λ°œκ²¬ν•  수 μžˆλ‹€.

1. κ°™κ±°λ‚˜ μ„œλΈŒ νƒ€μž…μΈ 경우, 할당이 κ°€λŠ₯ν•˜λ‹€. (곡변)

// primitive type
  let sub7: string = '';
  let sup7: string | number = sub7;

  // object - 각각의 ν”„λ‘œνΌν‹°κ°€ λŒ€μ‘ν•˜λŠ” ν”„λ‘œνΌν‹°μ™€ κ°™κ±°λ‚˜ μ„œλΈŒνƒ€μž…μ΄μ–΄μ•Ό ν•œλ‹€. 
  let sub8: { a: string; b: number } = { a: '', b: 1 };
  let sup8: { a: string | number; b: number } = sub8; 

  // array - object 와 λ§ˆμ°¬κ°€μ§€
  let sub9: Array<{ a: string; b: number }> = [{ a: '', b: 1 }]; 
  let sup9: Array<{ a: string | number; b: number }> = sub8;

νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” 기본적으둜 곡변을 λ”°λ₯Έλ‹€.

2. ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜ νƒ€μž…λ§Œ κ°™κ±°λ‚˜ μŠˆνΌνƒ€μž…μΈ 경우, 할당이 κ°€λŠ₯ν•˜λ‹€.(λ°˜λ³‘)

class Person {}
  class Developer extends Person { 
    coding() {}
  }
  class StartupDeveloper extends Developer { 
    burning() {}
  }

  function tellme(f: (d: Developer) => Developer) {}

  // Developer => Developer 에닀가 Developer => Developer λ₯Ό ν• λ‹Ήν•˜λŠ” 경우 
  tellme(function dToD(d: Developer): Developer {
  return new Developer(); 
  });

  // Developer => Developer 에닀가 Person => Developer λ₯Ό ν• λ‹Ήν•˜λŠ” 경우 
  tellme(function pToD(d: Person): Developer {
  return new Developer(); 
  });

  // Developer => Developer 에닀가 StartipDeveloper => Developer λ₯Ό ν• λ‹Ήν•˜λŠ” 경우 
  tellme(function sToD(d: StartupDeveloper): Developer {
  return new Developer(); 
  });

κ°€μž₯ λ§ˆμ§€λ§‰ tellme뢀뢄은 λ…Όλ¦¬μ μœΌλ‘œ μ•½κ°„μ˜ λ¬Έμ œκ°€ μžˆλ‹€.
StartupDeveloperκ°€ Developerκ°€ ν•˜μœ„νƒ€μž…μ΄κΈ° λ•Œλ¬Έμ΄λ‹€.

ν•˜μ§€λ§Œ μœ΅ν†΅μ„±μ„ λΆ€μ—¬ν•΄ νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” μ—λŸ¬λ₯Ό μ•ˆλ°œμƒμ‹œν‚€μ§€λ§Œ strictFunctionTypes μ˜΅μ…˜μ„ 켜면 μ—λŸ¬λ₯Ό λ°œμƒν•˜κ²Œ ν•œλ‹€.
μ΄λŠ” ν•¨μˆ˜λ₯Ό ν• λ‹Ήν•  μ‹œμ— ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜ νƒ€μž…μ΄ κ°™κ±°λ‚˜ μŠˆνΌνƒ€μž…μΈ κ²½μš°κ°€ μ•„λ‹Œ 경우, μ—λŸ¬λ₯Ό 톡해 κ²½κ³ ν•œλ‹€.


🎫 νƒ€μž… 별칭 (Type Alias)

Interface λž‘ λΉ„μŠ·ν•΄ λ³΄μ΄λ‚˜ 쑰금 λ‹€λ₯΄λ‹€.
Primitive, Union Type, Tuple, Function 을 λ‹€λ₯Έ μ΄λ¦„μœΌλ‘œ λΆ€λ₯΄κΈ° μœ„ν•΄ μ‚¬μš©ν•˜κ²Œ λœλ‹€.
λ§Œλ“€μ–΄μ§„ νƒ€μž…μ˜ refer둜 μ‚¬μš©ν•˜λŠ” 것이지 νƒ€μž…μ„ λ§Œλ“œλŠ”κ²ƒμ€ μ•„λ‹ˆλ‹€.

Aliasing Primitive

Primitiveλ₯Ό λ‹€λ₯Έ μ΄λ¦„μœΌλ‘œ λΆ€λ₯΄λŠ” 것이닀.
사싀 별 μ˜λ―Έκ°€ μ—†λ‹€.

type MyStringType = string; 
  const str = 'world';
  let myStr: MyStringType = 'hello'; 
  myStr = str;

Aliasing Union Type

μœ λ‹ˆμ˜¨ νƒ€μž…μ€ A 도 κ°€λŠ₯ν•˜κ³  B 도 κ°€λŠ₯ν•œ νƒ€μž…μœΌλ‘œ 길게 μ“°λŠ” κ±Έ μ§§κ²Œν•˜κ³  λ°˜λ³΅μ„ μ€„μΈλ‹€λŠ”λ° μ˜λ―Έκ°€ μžˆλ‹€.

let person: string | number = 0; 
  person = 'Mark';
  type StringOrNumber = string | number; 
  let another: StringOrNumber = 0;
  another = 'Anna'; 

Aliasing Tuple

νŠœν”Œ νƒ€μž…μ— 별칭을 μ€˜μ„œ μ—¬λŸ¬κ΅°λ°μ„œ μ‚¬μš©ν•  수 있게 ν•˜λŠ” κ²ƒμœΌλ‘œ Aliasing Union Typeκ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ λ°˜λ³΅μ„ 쀄인닀.

let person: [string, number] = ['Mark', 35]; 
  type PersonTuple = [string, number];
  let another: PersonTuple = ['Anna', 24];

Aliasing Function

이 λ˜ν•œ λ°˜λ³΅μ„ 쀄이고 ν•¨μˆ˜μ˜ 타이핑 양을 쀄여쀀닀.

type EatType = (food: string) => void;

'TypeScript' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

πŸ“’ TypeScript Compiler  (0) 2022.12.15
πŸ“˜ Basic Types  (0) 2022.12.09
TypeScript μ„€μΉ˜ν•˜κΈ°πŸŒŠ  (0) 2022.12.03
λŒ“κΈ€