πŸ“ κΈ°μˆ μ±… μŠ€ν„°λ””

23λ…„ 1μ›”λΆ€ν„° ν™œλ™ 쀑인 κ΅μœ‘μ—μ„œ, 뜻이 λ§žλŠ” λ™λ£Œλ“€κ³Ό ν•¨κ»˜ μ§„ν–‰ν•˜κ²Œ 된 μŠ€ν„°λ””
μ•žμœΌλ‘œλ„ κΎΈμ€€νžˆ 기술 μ„œμ μ„ 읽고 ν•¨κ»˜ λ°œμ „ν•˜λŠ” μ‹œκ°„μ΄ λ˜μ—ˆμœΌλ©΄ μ’‹κ² λ‹€!

7μž₯. μΈν„°νŽ˜μ΄μŠ€

  • μΈν„°νŽ˜μ΄μŠ€λŠ” 객체 ν˜•νƒœλ₯Ό μ„€λͺ…ν•˜λŠ” 또 λ‹€λ₯Έ 방법
  • types alias둜 μ •μ˜λœ 객체 νƒ€μž…κ³Ό μœ μ‚¬ν•˜μ§€λ§Œ 차별점 쑴재
    • 더 읽기 μ‰¬μš΄ 였λ₯˜ λ©”μ‹œμ§€
    • 더 λΉ λ₯Έ 컴파일러 μ„±λŠ₯
    • ν΄λž˜μŠ€μ™€μ˜ 더 λ‚˜μ€ μƒν˜Έ μš΄μš©μ„±

Type alias VS Interface

두 가지 λͺ¨λ‘ μ„Έλ―Έμ½œλ‘ κ³Ό μ‰Όν‘œ λ‘˜ λ‹€ κ°€λŠ₯ν•˜λ‹€.

μΈν„°νŽ˜μ΄μŠ€μ˜ νŠΉμ§•

  • 속성 증가λ₯Ό μœ„ν•΄ 병합이 κ°€λŠ₯ν•˜λ‹€.
  • ν΄λž˜μŠ€κ°€ μ„ μ–Έλœ ꡬ쑰의 νƒ€μž…μ„ ν™•μΈν•˜λŠ”λ° μ‚¬μš© κ°€λŠ₯ν•˜λ‹€.
  • 일반적으둜 μΈν„°νŽ˜μ΄μŠ€μ—μ„œ νƒ€μž… 검사기가 더 빨리 μž‘λ™ν•œλ‹€. λ‚΄λΆ€μ μœΌλ‘œ 더 μ‰½κ²Œ μΊμ‹œν•  수 μžˆλŠ” λͺ…λͺ…λœ νƒ€μž…μ„ μ„ μ–Έν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.
  • 이름 μ—†λŠ” 객체 λ¦¬ν„°λŸ΄μ˜ 별칭이 μ•„λ‹Œ 이름이 μžˆλŠ” ν•˜λ‚˜μ˜ 객체둜 κ°„μ£Όλ˜λ―€λ‘œ 였λ₯˜ λ©”μ‹œμ§€λ₯Ό 쒀더 μ‰½κ²Œ 읽을 수 μžˆλ‹€.

읽기 μ „μš© 속성(readonly)

  • μΈν„°νŽ˜μ΄μŠ€μ— μ •μ˜λœ 객체의 속성을 μž¬ν• λ‹Ήν•˜μ§€ λͺ»ν•˜λ„둝 차단할 λ•Œ, readonly ν‚€μ›Œλ“œλ₯Ό μΆ”κ°€ν•œλ‹€.
  • readonly μ—°μ‚°μžλŠ” νƒ€μž… μ‹œμŠ€ν…œμ—λ§Œ μ‘΄μž¬ν•˜λ©° μΈν„°νŽ˜μ΄μŠ€μ—μ„œλ§Œ μ‚¬μš©ν•  수 μžˆλ‹€. 단지, 개발 쀑에 κ·Έ 속성이 μˆ˜μ •λ˜μ§€ λͺ»ν•˜λ„둝 λ³΄ν˜Έν•œλ‹€.

λ©”μ„œλ“œμ™€ 속성 ν•¨μˆ˜

  • λ©”μ„œλ“œ ꡬ문: test(): void;
  • 속성 ν•¨μˆ˜ ꡬ문: test: () => void;

λ©”μ„œλ“œλŠ” readonly 선언이 λΆˆκ°€λŠ₯, 속성 ν•¨μˆ˜λŠ” κ°€λŠ₯

호좜 μ‹œκ·Έλ‹ˆμ²˜

ν•¨μˆ˜ νƒ€μž…κ³Ό μœ μ‚¬ν•˜μ§€λ§Œ, 콜둠(:)이 μ•„λ‹Œ ν™”μ‚΄ν‘œ(=>)둜 ν‘œμ‹œν•œλ‹€.

interface TestImpl {
  (input: string): number;
}

const test: TestImpl = (input: string) => input.length;

인덱슀 μ‹œκ·Έλ‹ˆμ²˜

  • μžλ°”μŠ€ν¬λ¦½νŠΈ 객체 속성 μ‘°νšŒλŠ” μ•”λ¬΅μ μœΌλ‘œ ν‚€λ₯Ό λ¬Έμžμ—΄λ‘œ λ³€ν™˜ν•˜κΈ° λ•Œλ¬Έμ— μΈν„°νŽ˜μ΄μŠ€μ˜ κ°μ²΄λŠ” 일반적으둜 λ¬Έμžμ—΄ ν‚€λ₯Ό μ‚¬μš©ν•œλ‹€.
interface Example {
  [i: string]: number;
}
  • 인덱슀 μ‹œκ·Έλ‹ˆμ²˜λŠ” 객체에 값을 ν• λ‹Ήν•  λ•Œ νŽΈλ¦¬ν•˜μ§€λ§Œ νƒ€μž… μ•ˆμ •μ„±μ„ μ™„λ²½ν•˜κ²Œ 보μž₯ν•˜μ§€λŠ” λͺ»ν•œλ‹€.
  • λͺ…λͺ…λœ 속성이 더 ꡬ체적인 νƒ€μž…μ„ μ œκ³΅ν•˜κ³ , λ‹€λ₯Έ λͺ¨λ“  속성은 인덱슀 μ‹œκ·Έλ‹ˆμ²˜μ˜ νƒ€μž…μ„ λŒ€μ²΄ν•˜λŠ” κ²ƒμœΌλ‘œ ν˜Όν•©ν•΄μ„œ μ‚¬μš©ν•  수 μžˆλ‹€.
  • μΌλ°˜μ μœΌλ‘œλŠ” 인덱슀 μ‹œκ·Έλ‹ˆμ²˜μ˜ μ›μ‹œ 속성보닀 더 ꡬ체적인 속성 νƒ€μž… λ¦¬ν„°λŸ΄μ„ μ‚¬μš©ν•œλ‹€.
interface Dog {
  name: 'hodu'; // 더 ꡬ체적인 λ¦¬ν„°λŸ΄
  [i: string]: string;
}

μΈν„°νŽ˜μ΄μŠ€ ν™•μž₯

  • μΈν„°νŽ˜μ΄μŠ€κ°€ λ‹€λ₯Έ μΈν„°νŽ˜μ΄μŠ€μ˜ λͺ¨λ“  멀버λ₯Ό λ³΅μ‚¬ν•΄μ„œ μ„ μ–Έν•  수 μžˆλŠ” ν™•μž₯된 μΈν„°νŽ˜μ΄μŠ€
  • ν™•μž₯ν•  μΈν„°νŽ˜μ΄μŠ€μ˜ 이름 뒀에 extends ν‚€μ›Œλ“œλ₯Ό μΆ”κ°€ν•œλ‹€.

μž¬μ •μ˜λœ 속성

  • νƒ€μž… κ²€μ‚¬κΈ°λŠ” μž¬μ •μ˜λœ 속성이 κΈ°λ³Έ 속성에 ν• λ‹Ήλ˜μ–΄μžˆλ„λ‘ κ°•μš”ν•œλ‹€.
  • 즉, μž¬μ •μ˜ν•œ 속성은 이전 μ •μ˜λ³΄λ‹€ 더 쒁은 λ²”μœ„μ—¬μ•Ό ν•œλ‹€.

닀쀑 μΈν„°νŽ˜μ΄μŠ€ ν™•μž₯

  • μΈν„°νŽ˜μ΄μŠ€λŠ” μ—¬λŸ¬ 개의 μΈν„°νŽ˜μ΄μŠ€λ₯Ό ν™•μž₯ν•΄μ„œ μ„ μ–Έν•  수 μžˆλ‹€.
  • extends ν‚€μ›Œλ“œ 뒀에 μ‰Όν‘œλ‘œ μΈν„°νŽ˜μ΄μŠ€ 이름을 ꡬ뢄해 μ‚¬μš©ν•˜λ©΄ λœλ‹€.

μΈν„°νŽ˜μ΄μŠ€ 병합

  • μ—¬λŸ¬ 개의 μΈν„°νŽ˜μ΄μŠ€κ°€ λ™μΌν•œ μ΄λ¦„μœΌλ‘œ λ™μΌν•œ μŠ€μ½”ν”„μ— μ„ μ–Έλœ 경우, μ„ μ–Έλœ λͺ¨λ“  ν•„λ“œλ₯Ό ν¬ν•¨ν•˜λŠ” 더 큰 μΈν„°νŽ˜μ΄μŠ€κ°€ λœλ‹€.
  • μΈν„°νŽ˜μ΄μŠ€ 병합을 자주 μ‚¬μš©ν•˜μ§€λŠ” μ•ŠλŠ”λ‹€.
  • μΈν„°νŽ˜μ΄μŠ€ 병합은 μ™ΈλΆ€ νŒ¨ν‚€μ§€ λ˜λŠ” Window와 같은 λ‚΄μž₯된 μ „μ—­ μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ³΄κ°•ν•˜λŠ”λ° 특히 μœ μš©ν•˜λ‹€.

이름이 μΆ©λŒλ˜λŠ” 멀버

  • 속성이 이미 μΈν„°νŽ˜μ΄μŠ€μ— μ„ μ–Έλ˜μ–΄ μžˆλ‹€λ©΄ λ‚˜μ€‘μ— λ³‘ν•©λœ μΈν„°νŽ˜μ΄μŠ€μ—μ„œλ„ λ™μΌν•œ λ™μΌν•œ νƒ€μž…μ„ μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.
  • 같은 μ΄λ¦„μ˜ 속성이 νƒ€μž…μ΄ μ„œλ‘œ λ‹€λ₯΄λ©΄ 였λ₯˜κ°€ λ°œμƒν•œλ‹€.
  • λ‹€λ§Œ, λ™μΌν•œ 이름과 λ‹€λ₯Έ μ‹œκ·Έλ‹ˆμ²˜λ₯Ό 가진 λ©”μ„œλ“œλŠ” μ •μ˜ν•  수 μžˆλ‹€.(ν•¨μˆ˜ μ˜€λ²„λ‘œλ“œ)

8. 클래슀

λͺ…심할 λ‚΄μš©: νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” 클래슀 μ‚¬μš©μ΄λ‚˜ λ‹€λ₯Έ 인기 μžˆλŠ” μžλ°”μŠ€ν¬λ¦½νŠΈ νŒ¨ν„΄μ„ ꢌμž₯ν•˜μ§€λ„ 막지도 μ•ŠλŠ”λ‹€.

개인적인 생각: κ·Έλ ‡μ§€λ§Œ μžλ°” μ–Έμ–΄κ°€ 클래슀둜 객체λ₯Ό ν‘œν˜„ν•˜λŠ” 객체 지ν–₯ μ–Έμ–΄μΈλ§ŒνΌ νƒ€μž…μŠ€ν¬λ¦½νŠΈλ„ 클래슀둜 κ΅¬ν˜„μ„ 많이 ν•˜λŠ” 것 κ°™λ‹€.

클래슀 속성

  • νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œ 클래슀의 속성을 μ½κ±°λ‚˜ μ“°λ €λ©΄ ν΄λž˜μŠ€μ— λͺ…μ‹œμ μœΌλ‘œ μ„ μ–Έν•΄μ•Όν•œλ‹€.
class Example {
  test: string; // 이런 μ‹μœΌλ‘œ μ†μ„±μ˜ νƒ€μž…μ„ λͺ…μ‹œμ μœΌλ‘œ μ„ μ–Έν•΄μ•Όλœλ‹€.
  constructor() {
    this.test = 'ttt';
  }
}

νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” 생섲아 λ‚΄μ˜ 할당에 λŒ€ν•΄μ„œ κ·Έ 멀버가 ν΄λž˜μŠ€μ— μ†μž¬ν•˜λŠ” 멀버인지 μΆ”λ‘ ν•˜λ €κ³  μ‹œλ„ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 즉, μœ„μ²˜λŸΌ λͺ…μ‹œλ₯Ό 해주지 μ•ŠμœΌλ©΄ TSκ°€ 슀슀둜 μΆ”λ‘ ν•˜μ§€ λͺ»ν•˜λŠ” 것을 μ˜λ―Έν•œλ‹€.

ν•¨μˆ˜ 속성

class T {
	arrow: () => void;
	constructor() {
		this.arrow = () => {
			console.log(this)
		}
	}

	nonArrow() {
		console.log(this)
	}
}

const t = new T();
t.arrow(); // 'T: {}'κ°€ μ°νžŒλ‹€.
t.nonArrow(); // 'T: {}'κ°€ μ°νžŒλ‹€.
t.arrow.bind('arrowμž…λ‹ˆλ‹€.')(); // 'T: {}'κ°€ μ°νžŒλ‹€.
t.nonArrow.bind('λ©”μ„œλ“œμž…λ‹ˆλ‹€.')(); // 'λ©”μ„œλ“œμž…λ‹ˆλ‹€.'κ°€ μ°νžŒλ‹€.
class T {
  t = 111;
}
// μœ„μ™€ μ•„λž˜λŠ” 같은 ν‘œν˜„μ΄λ‹€.
class T {
  t: number;
  constructor() {
    this.t = 111
  }
}

μ΄ˆκΈ°ν™” 검사

  • μ—„κ²©ν•œ 컴파일러 섀정이 ν™œμ„±ν™”λœ μƒνƒœμ—μ„œλŠ” νƒ€μž…μŠ€ν¬λ¦½νŠΈκ°€ undefined νƒ€μž…μœΌλ‘œ μ„ μ–Έλœ 각 속성이 μƒμ„±μžμ—μ„œ ν• λ‹Ήλ˜μ—ˆλŠ”μ§€ ν™•μΈν•œλ‹€.

μ—„κ²©ν•œ μ΄ˆκΈ°ν™” 검사λ₯Ό μ μš©ν•˜λ©΄ μ•ˆλ˜λŠ” 속성인 κ²½μš°μ—λŠ” 이름 λ’€μ—μ„œ !λ₯Ό μΆ”κ°€ν•˜μ—¬ 검사λ₯Ό λΉ„ν™œμ„±ν™”ν•  수 μžˆλ‹€. κ·ΈλŸ¬λ‚˜ μ΄λŠ” type을 any둜 λ‘λŠ” 것과 같이 νƒ€μž… μ•ˆμ •μ„±μ„ μ€„μ΄λŠ” ν–‰μœ„μ΄λ―€λ‘œ 가급적이면 μ½”λ“œλ₯Ό λ¦¬νŒ©ν† λ§ν•˜μž.

읽기 μ „μš© 속성

  • readonly둜 μ„ μ–Έλœ 속성은 μ„ μ–Έλœ μœ„μΉ˜ λ˜λŠ” μƒμ„±μžμ—μ„œ μ΄ˆκΉƒκ°’λ§Œ ν• λ‹Ήν•  수 μžˆλ‹€. ν•΄λ‹Ή 속성은 읽을 수만 있고 값을 λ³€κ²½ν•  μˆ˜λŠ” μ—†λ‹€.
  • let이 μ•„λ‹Œ const둜 λ³€μˆ˜λ₯Ό ν• λ‹Ήν•˜λŠ” 것과 μœ μ‚¬ν•˜λ‹€.(μΆ”ν›„ μ΄ˆκΈ°ν™” 및 μƒˆλ‘œμš΄ κ°’ 할당이 λΆˆκ°€λŠ₯ν•˜λ‹€.)

readonlyλŠ” TSμ—λ§Œ μ‘΄μž¬ν•˜λŠ” κΈ°λŠ₯이닀. κ·ΈλŸ¬λ―€λ‘œ μ§„μ •ν•œ 읽기 μ „μš© λ³΄ν˜Έκ°€ ν•„μš”ν•˜λ‹€λ©΄ privateμ΄λ‚˜ getterλ₯Ό μ‚¬μš©ν•˜μž.

νƒ€μž…μœΌλ‘œμ„œμ˜ 클래슀

  • νƒ€μž… μ‹œμŠ€ν…œμ—μ„œμ˜ ν΄λž˜μŠ€λŠ” λŸ°νƒ€μž„ μ‹œμ˜ κ°’(클래슀 객체 자체)κ³Ό νƒ€μž…μœΌλ‘œμ„œλ„ μƒμ„±λœλ‹€.
  • 클래슀의 λ™μΌν•œ(이름이 같은) 멀버λ₯Ό λͺ¨λ‘ ν¬ν•¨ν•˜λŠ” λͺ¨λ“  객체 νƒ€μž…μ„ κ·Έ ν΄λž˜μŠ€μ— ν• λ‹Ήν•  수 μžˆλŠ” κ²ƒμœΌλ‘œ κ°„μ£Όν•œλ‹€.
    • μ΄λŠ” νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ ꡬ쑰적 타이핑이 μ„ μ–Έλ˜λŠ” 방식이 μ•„λ‹ˆλΌ 객체의 ν˜•νƒœλ§Œ κ³ λ €ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.
class Example {
  test: () => void;

  constructor() {
    this.test = () => {
      console.log('test');
    }
  }
}

const example: Example = { 
  test() {
    console.log('κ°μ²΄μž…λ‹ˆλ‹€.')
  }
}
// class μƒμ„±μžλ₯Ό 톡해 μƒμ„±λœ 객체가 μ•„λ‹Œ, 객체 λ¦¬ν„°λŸ΄μž„μ—λ„ λ™μΌν•œ λ©€λ²„λ§Œ κ°–κ³  μžˆλ‹€λ©΄ 할당이 κ°€λŠ₯ν•˜λ‹€.

μ–΄λ–»κ²Œ 보면 μ‘°κΈˆμ€ ν—ˆμˆ ν•΄λ³΄μΌ 수 μžˆμ§€λ§Œ, μ‹€μ œλ‘œ μš°λ¦¬κ°€ μ½”λ“œλ₯Ό μž‘μ„±ν•  λ•Œ class둜 μ„ μ–Έλœ νƒ€μž…μ„ κ°€μ Έμ™€μ„œ 객체 λ¦¬ν„°λŸ΄λ‘œ 값을 ν• λ‹Ήν•˜λŠ” 일은 거의 μ—†λ‹€.

ν΄λž˜μŠ€μ™€ μΈν„°νŽ˜μ΄μŠ€

  • 클래슀 이름 뒀에 implements ν‚€μ›Œλ“œμ™€ μΈν„°νŽ˜μ΄μŠ€ 이름을 μΆ”κ°€ν•¨μœΌλ‘œμ¨ 클래슀의 μΈμŠ€ν„΄μŠ€κ°€ 이 μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ”°λ₯Έλ‹€κ³  μ„ μ–Έν•  수 μžˆλ‹€.
interface ExampleImpl {
  test: string;
}

class Example implements ExampleImpl {
  test: string;
  constructor() {
    this.test = 'testμž…λ‹ˆλ‹€.';
  }
}
  • νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” μΈν„°νŽ˜μ΄μŠ€μ—μ„œ 클래슀의 λ©”μ„œλ“œ λ˜λŠ” 속성 νƒ€μž…μ„ μœ μΆ”ν•˜μ§€ μ•ŠλŠ”λ‹€.
interface ExampleImpl {
  test: string;
  do: (something: string) => void;
  play: (something: string) => void;
}

class Example implements ExampleImpl {
  test; // ν”„λ‘œνΌν‹°λŠ” μ—λŸ¬ μ•ˆλ‚¨.
  play; // ν”„λ‘œνΌν‹°λ‘œ μ„ μ–Έλœ ν•¨μˆ˜ μžμ²΄λŠ” μ—λŸ¬ μ•ˆλ‚¨.
  constructor() {
    this.test = 'testμž…λ‹ˆλ‹€.';
    this.play = (something) => { // Parameter 'something' implicitly has an 'any' type. μ—¬κΈ°μ„œ νƒ€μž… μ—λŸ¬ λ°œμƒ
      console.log(`Let's play ${something}`)
    }
  }
  do(something) { // Parameter 'something' implicitly has an 'any' type.
    console.log(something);
  }
}

// 즉, something μΈμžλŠ” string으둜 μΆ”λ‘ λ˜μ§€ λͺ»ν•˜κ³  any νƒ€μž…μœΌλ‘œ μ§€μ •λœλ‹€. κ·ΈλŸ¬λ‹ˆκΉŒ μœ„μ™€ 같은 any νƒ€μž… 였λ₯˜κ°€ λ‚˜μ˜€λŠ” 것이닀.

μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜λŠ” 것은 μˆœμ „νžˆ μ•ˆμ •μ„± 검사λ₯Ό μœ„ν•¨μ΄λ‹€!

닀쀑 μΈν„°νŽ˜μ΄μŠ€ κ΅¬ν˜„

interface FirstImpl {}
interface SecondImpl {}

class Example implements FirstImpl, SecondImpl {} // λ‘κ°œμ˜ μΈν„°νŽ˜μ΄μŠ€μ˜ κ·œμΉ™μ„ λͺ¨λ‘ λ‹€ μ§€μΌœμ•Ό ν•œλ‹€.

좔상 클래슀(Abstract Class)

일뢀 λ©”μ„œλ“œμ˜ κ΅¬ν˜„μ„ μ„ μ–Έν•˜μ§€ μ•Šκ³ , ν•˜μœ„ ν΄λž˜μŠ€κ°€ ν•΄λ‹Ή λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•  것을 μ˜ˆμƒν•˜μ—¬ κΈ°λ³Έ 클래슀λ₯Ό λ§Œλ“€ λ•Œ μ‚¬μš©ν•œλ‹€.

  • class μ•žμ— abstractλ₯Ό μΆ”κ°€ν•œλ‹€.
  • μƒμ„±μžλ‘œμ„œμ˜ 역할은 ν•˜μ§€ λͺ»ν•œλ‹€.

멀버 μ ‘κ·Όμ„±

  • public(default): μ–΄λ””μ„œλ‚˜ μ ‘κ·Ό κ°€λŠ₯
  • protected: ν•΄λ‹Ή 클래슀 λ‚΄λΆ€ λ˜λŠ” ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œλ§Œ μ ‘κ·Ό κ°€λŠ₯
  • private: ν•΄λ‹Ή 클래슀 λ‚΄λΆ€μ—μ„œλ§Œ μ ‘κ·Ό κ°€λŠ₯

JSμ—μ„œλŠ” μ•”λ¬΅μ μœΌλ‘œ protectedλŠ” _ ν‘œμ‹œν•˜κ³  privateλŠ” #으둜 정말 private의 κΈ°λŠ₯을 가진닀. TS의 멀버 접근성은 νƒ€μž… μ‹œμŠ€ν…œμ—λ§Œ μ‘΄μž¬ν•˜λŠ” 반면, JS의 privateλŠ” λŸ°νƒ€μž„μ—λ„ μ‘΄μž¬ν•œλ‹€.

정적 ν•„λ“œ μ œν•œμž

  • classμ—μ„œ static λ˜ν•œ readonlyκ°€ μ μš©λœλ‹€.