λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

Language/TypeScript

[TypeScript] TypeScript νƒ€μž… 정리

 

Object

λ³€μˆ˜λͺ…: { key1: νƒ€μž…, key2: νƒ€μž…, ... }
  • λ³€μˆ˜ 선언문을 ν™•μž₯ν•΄ μœ„μ™€ 같은 ν˜•νƒœλ‘œ νƒ€μž…μ„ λͺ…μ‹œν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • νƒ€μž… 주석(type annotation)이라고 ν•©λ‹ˆλ‹€.
  • μ˜ˆμ‹œ
const player: { name: string; age: number } = {
  name: "kim",
};

 


Optional

λ³€μˆ˜/ν”„λ‘œνΌν‹°λͺ…?: νƒ€μž…
  • λ¬ΌμŒν‘œλ₯Ό λΆ™μ—¬μ„œ νŠΉμ • ν”„λ‘œνΌν‹°λ‚˜ ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜λ₯Ό μ˜΅μ…”λ„λ‘œ λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ˜ˆμ‹œ
// μΈν„°νŽ˜μ΄μŠ€ ν”„λ‘œνΌν‹°μ— 적용
interface PaintOptions {
  shape: Shape;
  xPos?: number;
  yPos?: number;
}

// 객체 ν”„λ‘œνΌν‹°μ— 적용
const player: { name: string, age?: number } = {
  name: 'kim'
};

// ERROR
if (player.age < 10) {...}

 


Type Alias

type μƒˆλ‘œμš΄ νƒ€μž… = κΈ°μ‘΄ νƒ€μž…
  • type ν‚€μ›Œλ“œλ‘œ 기쑴에 μ‘΄μž¬ν•˜λŠ” νƒ€μž…μ„ μ΄λ¦„λ§Œ λ°”κΏ”μ„œ μ‚¬μš©ν•  수 있게 ν•΄μ€λ‹ˆλ‹€.
  • νƒ€μž…μ„ μž¬μ‚¬μš©ν•˜κ³  싢을 λ•Œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ½”λ“œκ°€ κΉ”λ”ν•˜κ³  λͺ…ν™•ν•΄μ§ˆ λ•ŒκΉŒμ§€λ§Œ μ‚¬μš©ν•˜λ©΄ λ©λ‹ˆλ‹€.
  • μ˜ˆμ‹œ
// μΈν„°νŽ˜μ΄μŠ€ ν”„λ‘œνΌν‹°μ— 적용
interface PaintOptions {
  shape: Shape;
  xPos?: number;
  yPos?: number;
}

// 객체 ν”„λ‘œνΌν‹°μ— 적용
const player: { name: string, age?: number } = {
  name: 'kim'
};

// ERROR
if (player.age < 10) {...}

 


Call Signature

(λ§€κ°œλ³€μˆ˜1: νƒ€μž…, λ§€κ°œλ³€μˆ˜2: νƒ€μž…, ...) => λ°˜ν™˜κ°’ νƒ€μž…
  • Call SignatureλŠ” ν•¨μˆ˜μ˜ νƒ€μž…μ„ λ§ν•©λ‹ˆλ‹€. 'ν•¨μˆ˜ μ‹œκ·Έλ‹ˆμ²˜'라고도 ν•©λ‹ˆλ‹€.
  • ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜ νƒ€μž…κ³Ό λ°˜ν™˜ νƒ€μž…μ„ μž‘μ„±ν•΄μ£Όμ–΄μ•Ό ν•©λ‹ˆλ‹€.
  • type을 μ‚¬μš©ν•˜λ©΄ 더 κΉ”λ”ν•˜κ²Œ μ •μ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ˜ˆμ‹œ
type Add = (a: number, b: number) => number;

const add: Add = (a, b) => a + b;

+) Overloading

  • 같은 μ΄λ¦„μ˜ ν•¨μˆ˜κ°€ λ§€κ°œλ³€μˆ˜μ˜ κ°œμˆ˜λ‚˜ νƒ€μž…μ΄ λ‹€λ₯Ό λ•Œ λ˜λŠ” λ°˜ν™˜ νƒ€μž…μ΄ λ‹€λ₯Ό λ•Œ μ˜€λ²„λ‘œλ”©μ΄λΌκ³  ν•©λ‹ˆλ‹€.
  • 이λ₯Ό 톡해 μ—¬λŸ¬ 개의 call signatureλ₯Ό κ°€μ§ˆ 수 μžˆλ‹€.
  • μ˜ˆμ‹œ
// ❌ Don't
type Add = {
  (a: number, b: number): number;
  (a: number, b: number, c: number): number;
};

// λ˜λŠ”

// βœ… Do: λ°˜ν™˜ νƒ€μž…μ΄ κ°™λ‹€λ©΄ μ˜΅μ…”λ„ λ§€κ°œλ³€μˆ˜ μ‚¬μš©μ„ ꢌμž₯ν•©λ‹ˆλ‹€.
type Add = {
  (a: number, b: number, c?: number): number;
};

const add: Add = (a, b, c) => {
  if (c) {
    return a + b + c;
  }
  return a + b;
};

 


Generic

  • ν•¨μˆ˜λ‚˜ 클래슀의 μ„ μ–Έ μ‹œμ μ΄ μ•„λ‹Œ, μ‚¬μš© μ‹œμ μ— νƒ€μž…μ„ μ„ μ–Έν•  수 μžˆλŠ” 방법을 μ œκ³΅ν•©λ‹ˆλ‹€.
  • λ³€μˆ˜/ν•¨μˆ˜λͺ… 뒀에 <νƒ€μž… λ³€μˆ˜ 이름> 뢙인 ν˜•νƒœλ‘œ μ‚¬μš©ν•©λ‹ˆλ‹€. νƒ€μž… λ³€μˆ˜μ˜ 이름은 μ•„λ¬΄κ±°λ‚˜ 해도 μƒκ΄€μ—†μ§€λ§Œ, κ΄€μŠ΅μ μœΌλ‘œ μ•ŒνŒŒλ²³ λŒ€λ¬Έμž ν•œκΈ€μžλ‘œ μ²˜λ¦¬ν•˜λŠ” νŽΈμž…λ‹ˆλ‹€.(T, V, E, ...)
  • λΌμ΄λΈŒλŸ¬λ¦¬λ‚˜ λ‹€λ₯Έ κ°œλ°œμžκ°€ μ‚¬μš©ν•  κΈ°λŠ₯을 λ§Œλ“€ λ•Œ μœ μš©ν•˜κ²Œ μ“Έ 수 μžˆμŠ΅λ‹ˆλ‹€.

1. μ œλ„€λ¦­ ν•¨μˆ˜ νƒ€μž…

  • ν•¨μˆ˜ μ˜€λ²„λ‘œλ”©μ„ ν•  λ•Œ ν—ˆμš©ν•˜λŠ” κ³ μ • νƒ€μž…μ΄ λ§Žμ•„μ§ˆμˆ˜λ‘ μ½”λ“œμ˜ 가독성이 λ–¨μ–΄μ§‘λ‹ˆλ‹€.
// call signature
type SuperPrint = {
  // concrete type: number, boolean, string
  (arr: number[]): void;
  (arr: boolean[]): void;
  (arr: string[]): void;
  (arr: (number | boolean)[]): void;
};

const superPrint: SuperPrint = (arr) => {
  arr.forEach((i) => console.log(i));
};

superPrint([1, 2, 3, 4]);
superPrint([true, true, false]);
superPrint(["a", "b", "c"]);
superPrint([1, 2, true, false]);
  • 이럴 λ•Œ μ œλ„€λ¦­μ„ μ‚¬μš©ν•˜λ©΄ νƒ€μž…μ„ λ³€μˆ˜ν™”ν•˜μ—¬ μœ μ—°ν•˜κ²Œ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
// 방법 1: type(λ˜λŠ” interface)으둜 νƒ€μž… μ§€μ •
type SuperPrint = {
  <T>(arr: T[]): T;
};
const superPrint: SuperPrint = (arr) => arr[0];

// 방법 2: ν•¨μˆ˜ 선언식
function superPrint<T>(arr: T[]) {
  return a[0];
}

// 방법 3: ν•¨μˆ˜ ν‘œν˜„μ‹
const superPrint = <T>(arr: T[]): T => arr[0];

const a = superPrint([1, 2, 3, 4]); // a: number
const b = superPrint([true, true, false]); // b: boolean
const c = superPrint(["a", "b", "c"]); // c: string
const d = superPrint([1, 2, true, false]); // d: number | boolean

2. μ œλ„€λ¦­ 객체 νƒ€μž…

  • 객체에도 μ œλ„€λ¦­ νƒ€μž…μ„ μ μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ˜ˆμ‹œ
type Player<T> = {
  name: string;
  extraInfo: T;
};

type ExtraInfo = {
  favoriteFood: string;
};

const nico: Player<ExtraInfo> = {
  name: "nico",
  extraInfo: {
    favoriteFood: "kimchi",
  },
};

 


readonly

  • 읽기 μ „μš©μœΌλ‘œ λ§Œλ“€μ–΄μ€λ‹ˆλ‹€. 즉, 'λΆˆλ³€μ„±'을 κ°€μ§€κ²Œ λ§Œλ“€μ–΄μ£ΌλŠ” κ²ƒμž…λ‹ˆλ‹€.
    •  λΆˆλ³€μ΄λž€?
      • λ³€μˆ˜κ°€ const둜 μ„ μ–Έλ˜κ±°λ‚˜ readonlyλ₯Ό λͺ…μ‹œν•˜κ³  있으면 μ΄ˆκΉƒκ°’μ„ 항상 μœ μ§€ν•©λ‹ˆλ‹€. μ΄λŸ¬ν•œ λ³€μˆ˜λ₯Ό λ³€κ²½ν•  수 μ—†λ‹€λŠ” 의미둜 'λΆˆλ³€(immutable)' λ³€μˆ˜λΌκ³  ν•©λ‹ˆλ‹€.
  • 적용 λŒ€μƒ : λ³€μˆ˜, 객체 ν”„λ‘œνΌν‹°, μΈν„°νŽ˜μ΄μŠ€ ν”„λ‘œνΌν‹°, 클래슀 ν”„λ‘œνΌν‹°, ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜ λ“±
    • 클래슀 ν”„λ‘œνΌν‹°μ— λŒ€ν•΄μ„œ, 값을 κ³΅κ°œλŠ” ν•˜κ³  μ‹Άμ§€λ§Œ μˆ˜μ •μ€ λͺ»ν•˜κ²Œ ν•˜κ³  싢을 λ•Œ readonlyλ₯Ό μ‚¬μš©ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
  • μ˜ˆμ‹œ 1
type Player = {
  readonly name: string;
};

const makePlayer = (name: string): Player => ({ name });

const player = makePlayer("kim");
player.name = "lee"; // ERROR
  • μ˜ˆμ‹œ 2
class Word {
  constructor(public readonly term: string, public readonly def: string) {}
}

 

+) readonly와 const의 μ°¨μ΄λŠ”?

  • readonlyλŠ” ν”„λ‘œνΌν‹°λ₯Ό λΆˆλ³€μœΌλ‘œ λ§Œλ“€μ–΄μ€λ‹ˆλ‹€.
    • νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œ μΈν„°νŽ˜μ΄μŠ€ ν”„λ‘œνΌν‹°, 클래슀 ν”„λ‘œνΌν‹°, ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜ 등은 let, const ν‚€μ›Œλ“œ 없이 μ„ μ–Έν•©λ‹ˆλ‹€.
    • μ΄λŸ¬ν•œ 것듀에 λΆˆλ³€μ„±μ„ μ£Όλ €λ©΄ readonlyλ₯Ό μ“°λ©΄ λ©λ‹ˆλ‹€.
  • readonlyλŠ” λ°°μ—΄κ³Ό 객체λ₯Ό λΆˆλ³€μœΌλ‘œ λ§Œλ“€μ–΄μ€λ‹ˆλ‹€.
    • λ°°μ—΄κ³Ό λ¦¬ν„°λŸ΄ κ°μ²΄λŠ” const둜 μ„ μ–Έν•˜λ”λΌλ„ κ·Έ μ•ˆμ˜ μš”μ†Œλ“€μ„ λ³€κ²½ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    • λ°°μ—΄μ˜ μš”μ†Œμ™€ λ¦¬ν„°λŸ΄ 객체의 ν”„λ‘œνΌν‹°μ—λ„ λΆˆλ³€μ„±μ„ μ£Όκ³  μ‹ΆμœΌλ©΄ readonlyλ₯Ό μ‚¬μš©ν•˜λ©΄ λ©λ‹ˆλ‹€.
  • μ˜ˆμ‹œ
const numbers: readonly number[] = [1, 2, 3, 4];
numbers.push(5); // ERROR

function forcePure(array: readonly number[]) {
  array.push(1); // ERROR
}

 


Tuple

  • μš”μ†Œμ˜ νƒ€μž…μ΄ λͺ¨λ‘ κ°™μœΌλ©΄ λ°°μ—΄, λ‹€λ₯Ό μˆ˜λ„ 있으면 νŠœν”Œμž…λ‹ˆλ‹€.
  • 항상 μ •ν•΄μ§„ 개수의 μš”μ†Œλ₯Ό κ°€μ Έμ•Ό ν•˜λŠ” λ°°μ—΄μ˜ νƒ€μž…μ„ μ§€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • 배열은 νŠœν”Œμ— λͺ…μ‹œμ μœΌλ‘œ μ§€μ •λœ ν˜•μ‹μ— 따라 μš”μ†Œ μˆœμ„œλ₯Ό μ„€μ •ν•΄μ•Ό ν•˜κ³ , μΆ”κ°€λ˜λŠ” μš”μ†Œ λ˜ν•œ νŠœν”Œμ— λͺ…μ‹œλœ νƒ€μž…λ§Œ μ‚¬μš© κ°€λŠ₯ν•©λ‹ˆλ‹€.
  • μ˜ˆμ‹œ
const player: [string, number, boolean] = ["nico", 12, true];
player[0] = 1; // ERROR
player[0] = "lynn"; // OK

// readonly와 μ‘°ν•©ν•΄μ„œ μ“Έ μˆ˜λ„ μžˆλ‹€.
const player: readonly [string, number, boolean] = ["nico", 12, true];
player[0] = "lynn"; // ERROR

 


any

  • 말 κ·ΈλŒ€λ‘œ 아무 νƒ€μž…μ΄λ‚˜ 될 수 μžˆμŠ΅λ‹ˆλ‹€.
  • νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ νƒ€μž… 검사λ₯Ό λΉ μ Έλ‚˜μ˜€κ³  싢을 λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€.
  • anyλŠ” 사싀상 μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό μ“°λŠ” 것과 κ°™μœΌλ―€λ‘œ μ‹ μ€‘ν•˜κ²Œ μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.
  • μ˜ˆμ‹œ
const a: any[] = [1, 2, 3, 4];
const b: any = true;

a + b; // OK

 


unknown

  • λ³€μˆ˜μ˜ νƒ€μž…μ„ 미리 μ•Œ 수 없을 λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€.
  • any 처럼 μ–΄λ– ν•œ νƒ€μž…μ˜ 값이라도 ν• λ‹Ήν•  수 μžˆμ§€λ§Œ, unknown νƒ€μž…μ˜ 값을 μ‚¬μš©ν•˜κΈ° 전에 λ¨Όμ € νƒ€μž… 확인 μž‘μ—…μ„ ν•΄μ•Ό ν•©λ‹ˆλ‹€.
  • any보닀 νƒ€μž… μ•ˆμ •μ„±μ„ μœ μ§€ν•˜λ©΄μ„œ 동적인 νƒ€μž… μ²˜λ¦¬κ°€ ν•„μš”ν•  λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€.
  • μ˜ˆμ‹œ
let x: unknown = 10;
let y: string;

// ERROR
y = x;

// OK
if (typeof x === "string") {
  y = x;
}

 


void

  • 값을 λ°˜ν™˜ν•˜μ§€ μ•ŠλŠ” ν•¨μˆ˜μ˜ λ°˜ν™˜ νƒ€μž…μž…λ‹ˆλ‹€.
  • ν•¨μˆ˜μ˜ λ°˜ν™˜ νƒ€μž…μœΌλ‘œλ§Œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
function print(): void {
  console.log("hi!");
}

 


never

  • λ³€μˆ˜μ˜ νƒ€μž…μœΌλ‘œ μ‚¬μš©λ˜λ©΄ μ ˆλŒ€ λ°œμƒν•  수 μ—†λŠ” κ°’μ΄λΌλŠ” μ˜λ―Έμž…λ‹ˆλ‹€.
  • 보톡 ν•¨μˆ˜μ˜ λ°˜ν™˜ νƒ€μž…μœΌλ‘œ μ‚¬μš©λ˜λ©°, ν•¨μˆ˜κ°€ κ²°μ½” 값을 λ°˜ν™˜ν•˜μ§€ μ•ŠμŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€.
  • 주둜 μ˜ˆμ™Έλ₯Ό λ˜μ§€κ±°λ‚˜ λ¬΄ν•œ 루프와 같은 μž‘μ—…μ„ ν•˜λŠ” ν•¨μˆ˜μ—μ„œ λ°˜ν™˜ νƒ€μž…μœΌλ‘œ μ‚¬μš©λ©λ‹ˆλ‹€.
  • μ˜ˆμ‹œ
function fail(msg: string): never {
  throw new Error(msg);
}

function fn(x: string | number) {
  if (typeof x === "string") {
    // do something
  } else if (typeof x === "number") {
    // do something else
  } else {
    x; // has type 'never'!
  }
}

 

+) void vs never

  • void와 never λ‘˜ λ‹€ λ°˜ν™˜κ°’μ΄ μ—†λ‹€λŠ” 것은 κ°™μŠ΅λ‹ˆλ‹€.
  • voidλŠ” λ°˜ν™˜κ°’μ„ μƒμ„±ν•˜μ§€ μ•Šκ³  μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” λͺ©μ μž„을 μ˜λ―Έν•˜κ³ , neverλŠ” ν•¨μˆ˜κ°€ μ •μƒμ μœΌλ‘œ μ’…λ£Œλ˜μ§€ μ•ŠμŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€.

 

μ°Έκ³