Typescript: The Basics

@Troy Β· October 16, 2023 Β· 8 min read

🧐 νƒ€μž…μŠ€ν¬λ¦½νŠΈλ₯Ό μ•„μ„Έμš”?

νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” λ‚΄κ°€ 맀일 μ‚¬μš©ν•˜μ§€λ§Œ λ‚˜μ—κ²Œ "νƒ€μž…μŠ€ν¬λ¦½νŠΈλ₯Ό μž˜μ•„μ„Έμš”?"라고 ν•œλ‹€λ©΄ λ‚˜λŠ” "κ·Έ... 쓸쀄은 μ•Œμ•„μš”"라고만 말할 수 μžˆμ„ 것 κ°™λ‹€. 그러면 μž˜ν•˜λ €λ©΄ μ–΄λ–»κ²Œ ν•΄μ•Όν• κΉŒλ₯Ό κ³ λ―Όν•΄ 봀을 λ•Œ, λ‚˜μ—κ²Œ λ“€μ—ˆλ˜ 생각은 "고개λ₯Ό λ“€μ–΄ κ³΅μ‹λ¬Έμ„œλ₯Όλ₯Ό λ³΄κ²Œν•˜λΌ"μ˜€λ‹€. κ³΅μ‹λ¬Έμ„œ ν•œλ²ˆ 읽지 μ•Šκ³  μ–Όλ§ˆλ‚˜ μž˜ν•  수 μžˆμ„κΉŒ, 책보닀도 더 λΉ λ₯΄κ²Œ μ—…λ°μ΄νŠΈλ˜κ³  λˆ„κ°€ 봐도 잘 μ„€λͺ…ν•  수 있게 고민의 흔적이 λ‹΄κΈ΄ λ¬Έμ„œλŠ” κ³΅μ‹λ¬Έμ„œμ˜€λ‹€. κ·Έλž˜μ„œ ν•œλ²ˆλ„ 읽지 μ•Šμ•˜λ˜, κ³΅μ‹λ¬Έμ„œλ₯Ό 읽고 ν•œλ²ˆ 정리해보렀 ν•œλ‹€. μ˜μ–΄λ₯Ό ν•΄μ„ν•˜λ‹€ λ³΄λ‹ˆ μ˜€μ—­λ„ μžˆμ„ 수 있고 쓰닀보면 λ‚΄ λ§˜λŒ€λ‘œ μ“°λŠ” 말듀도 λ§Žκ² μ§€λ§Œ, 이왕 λ§ˆμŒλ¨Ήμ€ κ±° ν•˜λ£¨μ— ν•œνŽ˜μ΄μ§€μ”© λκΉŒμ§€ κΌ­ μž‘μ„±ν•΄λ³΄λ € ν•œλ‹€.

The Basics

νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” μ™œ ν•„μš”ν• κΉŒ? κ·Έλƒ₯ μ‚¬λžŒλ“€μ΄ 많이 μ“°κ³  ν˜„μ—…μ—μ„œ 많이 μ‚¬μš©ν•˜λ‹ˆκΉŒλΌκ³  λŒ€λ‹΅ν•΄λ„ ν‹€λ¦° 닡은 아닐 것이닀. ν•˜μ§€λ§Œ λ‚΄κ°€ 느꼈던 νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ ν•„μš”μ„±μ€ 개발자의 μƒμ‚°μ„±μ΄μ—ˆλ‹€.

개발자의 μƒμ‚°μ„±μ΄λž€ 말과 νƒ€μž…μ΄ μΆ”κ°€λ˜λŠ” κ²ƒμ΄λž‘ 무슨 상관인지... 였히렀 μ½”λ“œλŸ‰μ€ 더 많고 μ„ΈνŒ…λ„ λŠ˜μ–΄λ‚˜λŠ” 데, 뭘 더 λΉ λ₯΄κ²Œ ν•΄μ€€λ‹€λŠ” 거지 μ‹Άμ—ˆμ§€λ§Œ μ“°λ©΄ μ“Έμˆ˜λ‘ 이해할 수 μžˆμ—ˆλ‹€.

νƒ€μž…μŠ€ν¬λ¦½νŠΈ ν•Έλ“œλΆ 첫μž₯의 λ‚΄μš©λ„ λ™μΌν–ˆλ‹€. javascriptλ§ŒμœΌλ‘œλŠ” λ³€μˆ˜μ— λ‹΄κΈ΄κ²Œ ν•¨μˆ˜μΈμ§€ 객체인지 μ–΄λ–€ 것도 μ•Œ 수 μ—†λ‹€κ³ , κ°œλ°œμžκ°€ κ²°κ΅­ 값에 뭐가 λ‹΄κ²ΌλŠ”μ§€ 확인해야 ν•˜λŠ” λΆˆνŽΈν•¨μ„ λ§ν•˜κ³  μžˆμ—ˆλ‹€.

function fn(x) {
  return x.flip();
}

μžλ°”μŠ€ν¬λ¦½νŠΈ 적으둜 아무 문제 μ—†λŠ” μœ„ μ½”λ“œμ˜ param인 xκ°€ flipμ΄λΌλŠ” 속성에 ν•¨μˆ˜λ₯Ό 가지고 μžˆμ§€ μ•Šλ‹€λ©΄ Type errorκ°€ λ°œμƒν•˜κ²Œ 될 것이닀. λ§Œμ•½ μΈμžκ°€ μ–΄λ–€ νƒ€μž…μΈμ§€ μ•Œμ•˜λ‹€λ©΄ κ³Όμ—° μ΄λŒ€λ‘œ μ‚¬μš©ν–ˆμ„κΉŒ?

νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” μΆ”κ°€μ μœΌλ‘œ νƒ€μž…μ„ μΆ”κ°€μ μœΌλ‘œ μž‘μ„±ν•΄μ€˜μ•Ό ν•˜μ§€λ§Œ, κ°œλ°œμžκ°€ λ³€μˆ˜μ— λŒ€ν•œ νƒ€μž…μ„ 일일이 κΈ°μ–΅ν•˜μ§€ μ•Šμ•„λ„ 되게 도와주고, λŸ°νƒ€μž„μ—μ„œ μž‘μ„±λ˜λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈ μ½”λ“œμ— λ™μž‘/배포 전에 μ—λŸ¬λ₯Ό μž‘μ•„μ€ŒμœΌλ‘œμ¨ 생산성을 λ†’μ—¬μ£Όκ²Œ λœλ‹€.

[히히 λͺ»κ°€..]

random
random

Non-exception Failures

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” λ‹€μ–‘ν•œ μ—λŸ¬λ₯Ό λ§Œλ“€ 수 μžˆλŠ”λ°, μ΄λŸ¬ν•œ μ—λŸ¬λ“€μ„ νƒ€μž…μŠ€ν¬λ¦½νŠΈκ°€ λ¨Όμ € μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” μ‹œμ μ— κ°œλ°œμžμ—κ²Œ μ•Œλ €μ€„ 수 μžˆλ‹€.

  • μ—†λŠ” 속성에 μ ‘κ·Όν–ˆμ„ λ•Œ

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 객체의 μ—†λŠ” 속성에 μ ‘κ·Όν•˜κ²Œ 되면 undefined을 λ°˜ν™˜ν•œλ‹€. κ·Έλ ‡κΈ° λ•Œλ¬Έμ— μžλ°”μŠ€ν¬λ¦½νŠΈλ§ŒμœΌλ‘œλŠ” 아무 문제 없이 μ§€λ‚˜κ°€κ²Œ 되고 μš°λ¦¬κ°€ μ˜ˆμƒν•˜μ§€ λͺ»ν–ˆλ˜ μ—λŸ¬λ₯Ό λ§ˆμ£Όν•˜κ²Œ λœλ‹€.

non-exception
non-exception

  • μ˜€νƒ€κ°€ λ°œμƒν–ˆμ„ λ•Œ

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” μ˜€νƒ€λ₯Ό λ°œμƒν•΄λ„ μ•Œμ§€ λͺ»ν•œλ‹€. μ™œλƒλ©΄ μžˆμ„μ§€λ„(?) λͺ¨λ₯΄κΈ° λ•Œλ¬Έμ΄λ‹€. νƒ€μž…μ΄ μ—†κΈ° λ•Œλ¬Έμ— μ–΄λ–€ 값을 가지고 μžˆμ„μ§€ λͺ°λΌ μ˜€νƒ€μΈμ€„ λͺ¨λ₯Έλ‹€.

non-exception
non-exception

  • ν•¨μˆ˜κ°€ ν˜ΈμΆœλ˜μ§€ μ•Šμ•˜μ„ λ•Œ

ν•¨μˆ˜μžμ²΄λŠ” μ°Έμ‘°κ°’μœΌλ‘œ μ €μž₯λœλ‹€. ν˜ΈμΆœλ˜μ§€ μ•Šκ³  κ°’μœΌλ‘œ μ‚¬μš©λ  수 μžˆλŠ” 상황이라면 μš°λ¦¬κ°€ μ˜ˆμƒν•˜μ§€ λͺ»ν•œ 일이 νŽΌμ³μ§„λ‹€.

non-exception
non-exception

Types for Tooling

μœ„μ— μ–ΈκΈ‰ν•œ μ—λŸ¬λ“€μ€ μžλ°”μŠ€ν¬λ¦½νŠΈλ‘œ μ½”λ“œλ₯Ό μž‘μ„±ν•  λ•Œ ν”νžˆ λ°œμƒν•  수 μžˆλŠ” 상황이닀. μ΄λŸ¬ν•œ λ¬Έμ œμƒν™©μ„ ν•΄κ²°ν•˜λŠ” μ€‘μš”ν•œ 방법쀑 ν•˜λ‚˜λŠ” λ°”λ‘œ μ• μ΄ˆμ— λ¬Έμ œμƒν™©μ„ λ§Œλ“€μ§€ μ•ŠλŠ” 것이라고 ν•  수 μžˆλ‹€.

νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” 개발 λ‹Ήμ‹œμ— νƒ€μž…μ„ μ΄μš©ν•΄ μ–΄λ–€ 값에 μ ‘κ·Όν•  수 μžˆλŠ”μ§€λ₯Ό 보여쀄 수 있기 λ•Œλ¬Έμ— μ΄λŸ¬ν•œ μ—λŸ¬λ₯Ό λ¨Όμ € λ°©μ§€ν•˜λŠ” 데 큰 도움을 μ€€λ‹€.

tooling
tooling

tsc

tscλŠ” νƒ€μž…μŠ€ν¬λ¦½νŠΈλ‘œ μš°λ¦¬κ°€ μž‘μ„±ν•œ μ½”λ“œμ˜ νƒ€μž…μ„ 체크할 수 있게 ν•΄μ£ΌλŠ” compilerλ₯Ό μ˜λ―Έν•œλ‹€. μ‹€μ œ ν˜„μ—…μ—μ„œλŠ” tscλ₯Ό 이용과 github action λ˜λŠ” huskyλ₯Ό μ΄μš©ν•΄μ„œ μ½”λ“œκ°€ λ³‘ν•©λ˜κΈ° μ „ νƒ€μž…μ—λŸ¬κ°€ μ—†λŠ”μ§€ κ²€μ‚¬ν•œλ‹€.

  • --noEmitOnError

μ΄λŸ¬ν•œ tscλŠ” λ‹€μ–‘ν•œ 컴파일 μ˜΅μ…˜μ„ 가지고 μžˆλŠ”λ° 그쀑 noEmitOnErrorλŠ” νƒ€μž… μ—λŸ¬κ°€ μžˆμ„ κ²½μš°μ— μ»΄νŒŒμΌν•˜μ§€ μ•ŠλŠ” μ˜΅μ…˜μ΄λ‹€.

Explicit Types

이제 νƒ€μž…μŠ€ν¬λ¦½νŠΈλ‘œ νƒ€μž…μ„ μΈμžμ— ν• λ‹Ήν•΄λ³΄μž.

function greet(person: string, date: Date) {
  console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}


greet("Maddison", Date());

explicit
explicit
μœ„ μ½”λ“œλ₯Ό λ³΄μ•˜μ„ λ•ŒλŠ” μ–Έλœ©λ³΄λ©΄ μ•„λ¬΄λ¬Έμ œ μ—†μ–΄ λ³΄μ΄μ§€λ§Œ Date()λ₯Ό 톡해 λ°˜ν™˜λœ 결과값이 string이기 λ•Œλ¬Έμ— μ—λŸ¬κ°€ λ°œμƒν•œ 것을 λ³Ό 수 μžˆλ‹€.

νƒ€μž…μŠ€ν¬λ¦½νŠΈκ°€ Date()λ₯Ό μžλ™μœΌλ‘œ μΆ”λ‘ ν•΄μ€ŒμœΌλ‘œμ¨ λ°œμƒν•  수 μžˆλŠ” μ—λŸ¬λ₯Ό 미리 μ•Œλ €μ€„ 수 μžˆμ—ˆλ‹€.

Erased Types

function greet(person, date) {
    console.log("Hello ".concat(person, ", today is ").concat(date.toDateString(), "!"));
}
greet("Maddison", new Date());

μœ„ μ½”λ“œλ₯Ό 컴파일 해보면 javascriptμ½”λ“œλ‘œ μš°λ¦¬κ°€ μž‘μ„±λœ μ½”λ“œμ™€ λ‹€λ₯΄κ²Œ 컴파일된 κ²°κ³Όλ₯Ό λ³Ό 수 μžˆλ‹€.

μ΄λŠ” TSCκ°€ μš°λ¦¬κ°€ μ„€μ •ν•œ ECMAScript 버전에 맞게 컴파일 ν•œ κ²ƒμœΌλ‘œ λ§Œμ•½ es2015으둜 μ„€μ •ν•œλ‹€λ©΄ μš°λ¦¬κ°€ μž‘μ„±ν•œ κ·ΈλŒ€λ‘œ 컴파일 될 수 μžˆλ‹€.

function greet(person, date) {
    console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}
greet("Maddison", new Date());

TSC의 μ˜΅μ…˜ λͺ‡κ°€μ§€

λ§ˆμ§€λ§‰μœΌλ‘œ basics νŽ˜μ΄μ§€μ˜ λ‚΄μš©μ€ tsc의 세가지 μ˜΅μ…˜μ— λŒ€ν•΄ μ„€λͺ…ν•œλ‹€.

  • Strictness: tsconfig.json의 "strict": true둜 μ„€μ •μ‹œ strict λͺ¨λ“œλ‘œ μ½”λ“œλ₯Ό μž‘μ„±ν•˜κ²Œ ν•œλ‹€.
  • noImplicitAny: νƒ€μž… μ„€μ • 쀑 μ•”λ¬΅μ μœΌλ‘œ anyκ°€ ν• λ‹Ήλ˜λŠ” 것을 λ°©μ§€ν•˜λŠ” μ˜΅μ…˜μœΌλ‘œ 주둜 ν•¨μˆ˜μ˜ νƒ€μž…μ΄ 정해지지 μ•Šμ€ μΈμžμ™€ 같은 μ½”λ“œλ₯Ό μ—λŸ¬λ‘œ μž‘μ•„μ£ΌλŠ” μ˜΅μ…˜μ΄λ‹€.
  • strictNullChecks: nullκ³Ό undefined은 λ‘˜λ‹€ falsyν•œ 값이 μ§€λ§Œ λ‹€λ₯Έ κ²°κ³Όλ₯Ό λ§Œλ“€κΈ°λ„ ν•˜κΈ° λ•Œλ¬Έμ— λ‘˜μ„ μ •ν™•νžˆ 핸듀링 ν•  수 있게 μ—λŸ¬λ‘œ μž‘μ•„μ£ΌλŠ” μ˜΅μ…˜μ΄λ‹€.
@Troy
맀일의 μ‹œν–‰μ°©μ˜€λ₯Ό κΈ°λ‘ν•˜λŠ” κ°œλ°œμΌμ§€μž…λ‹ˆλ‹€.