Typescript: EveryDay Types

@Troy Β· October 17, 2023 Β· 7 min read

Everyday Types 😊

이제 기본적인 νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ νƒ€μž…λ“€μ— λŒ€ν•΄ μ•Œμ•„λ³΄μž. λŒ€λΆ€λΆ„ 기본적인 뢀뢄이라 크게 정리할 뢀뢄은 μ—†μ—ˆλ‹€.

Primitive

μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ κΈ°λ³Έ νƒ€μž…λ“€μΈ string, number, boolean이 λ™μΌν•˜κ²Œ νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œ μ‚¬μš©λœλ‹€.

Arrays

배열은 λ‘κ°€μ§€λ‘œ ν‘œν˜„ν•  수 μžˆλŠ”λ° [1,2,3]κ³Ό 같은 number λ°°μ—΄μ˜ 경우 number[]와 Array<number> λ‘κ°€μ§€λ‘œ λ‚˜νƒ€λ‚Ό 수 μžˆλ‹€.

any

anyλŠ” νƒ€μž…μŠ€ν¬λ¦½νŠΈλ₯Ό μ‚¬μš©ν•˜λ©΄μ„œ κ°€μž₯ 쓰지 λ§μ•„μ•Όν•˜λŠ” νƒ€μž…μœΌλ‘œ 유λͺ…ν•œλ°, κ·Έ μ΄μœ λŠ” anyλŠ” λͺ¨λ“  νƒ€μž…μ„ κ°μ‹ΈλŠ” κ°€μž₯ 큰 집합에 ν•΄λ‹Ήλ˜κΈ° λ•Œλ¬Έμ— μ–΄λ–€ νƒ€μž…μ„ 넣어도 νƒ€μž…μ²΄ν¬λ₯Ό 톡과할 수 μžˆλ‹€. κ·ΈλŸ¬λ―€λ‘œ anyλ₯Ό μ§€μ–‘ν•˜μž.

Type annotation

νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” λ˜‘λ˜‘ν•΄μ„œ μš°λ¦¬κ°€ ν• λ‹Ήν•œ λ³€μˆ˜μ˜ 값에 따라 νƒ€μž…μ— 따라 νƒ€μž…μ„ μΆ”λ‘ ν•  수 μžˆλŠ”λ°, 덕뢄에 primitive νƒ€μž…μ˜ 값듀은 ꡳ이 νƒ€μž…μ„ μ •ν•˜μ§€ μ•Šμ•„λ„ μ μ ˆν•˜κ²Œ λΆ€μ—¬ν•  수 μžˆλ‹€.

/ No type annotation needed -- 'myName' inferred as type 'string'
let myName = "Alice";

Functions

μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ ν•¨μˆ˜λŠ” νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œ ν•„μš”ν•œ νƒ€μž… μ •λ³΄λŠ” 두가지, μΈμžμ™€ λ°˜ν™˜κ°’μ΄λ‹€.

인자의 νƒ€μž…μ„ μ „λ‹¬ν•˜μ§€ μ•Šκ³  noImplicitAny μ˜΅μ…˜μ΄ μΌœμ Έμžˆμ„ κ²½μš°μ— νƒ€μž…μ—λŸ¬κ°€ 뜨게 λ˜λ‹ˆ ν•¨μˆ˜μ˜ μΈμžμ— νƒ€μž…μ„ μ •ν•΄μ£Όμž. νƒ€μž…μ€ 각 인자 뒀에 μ •ν•΄μ£Όλ©΄ λœλ‹€.

// Parameter type annotation
function greet(name: string) {
  console.log("Hello, " + name.toUpperCase() + "!!");
}

λ°˜ν™˜κ°’μ€ νŠΉλ³„ν•œ 인자λ₯Ό κ°μ‹ΈλŠ” () λ‹€μŒμ— νƒ€μž…μ„ λ„£μ–΄μ£Όμž. λ°˜ν™˜κ°’μ΄ μ—†λ‹€λ©΄ μžλ™μœΌλ‘œ voidνƒ€μž…μœΌλ‘œ μΆ”λ‘ λœλ‹€.

function getFavoriteNumber(): number {
  return 26;
}

Anonymous function의 κ²½μš°λŠ” νŠΉμ΄ν•˜κ²Œ μΈμžμ— νƒ€μž…μ„ μ „λ‹¬ν•˜μ§€ μ•Šμ•„λ„ νƒ€μž…μŠ€ν¬λ¦½νŠΈκ°€ μžλ™μœΌλ‘œ νƒ€μž…μ„ μΆ”λ‘ ν•΄μ€€λ‹€. μ΄λŸ¬ν•œ 게 κ°€λŠ₯ν•œ μ΄μœ λŠ” contextual typing을 μ΄μš©ν•˜κΈ° λ•Œλ¬ΈμœΌλ‘œ, μ½œλ°±ν•¨μˆ˜λ‘œ μ–΄λ–€ 값이 전달 될 지 μΆ©λΆ„νžˆ μΆ”λ‘ ν•  수 있기 λ•Œλ¬Έμ΄λ‹€.

const names = ["Alice", "Bob", "Eve"];
 
// Contextual typing for function - parameter s inferred to have type string
names.forEach(function (s) {
  console.log(s.toUpperCase());
});
 
// Contextual typing also applies to arrow functions
names.forEach((s) => {
  console.log(s.toUpperCase());
});

Object

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ primitive νƒ€μž…μ„ μ œμ™Έν•˜λ©΄ λͺ¨λ‘ 객체라고 ν•  수 μžˆλ‹€.

// The parameter's type annotation is an object type
function printCoord(pt: { x: number; y: number }) {
  console.log("The coordinate's x value is " + pt.x);
  console.log("The coordinate's y value is " + pt.y);
}
printCoord({ x: 3, y: 7 });

νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œμ˜ ?λŠ” μ˜΅μ…”λ„ μ†μ„±μœΌλ‘œ 없을 κ²½μš°μ— runtimeμ—λŸ¬κ°€ λ‚˜λŠ” 것이 μ•„λ‹ˆλΌ undefined으둜 λ°˜ν™˜λ  수 있게 νƒ€μž…μ„ ν—ˆμš©ν•œλ‹€.

function printName(obj: { first: string; last?: string }) {
  // ...
}
// Both OK
printName({ first: "Bob" });
printName({ first: "Alice", last: "Alisson" });

Union Type

이제 νƒ€μž…μŠ€ν¬λ¦½νŠΈλ§Œμ˜ νƒ€μž…μ„ μ†Œκ°œν•˜λ € ν•œλ‹€. Union type은 두가지 νƒ€μž…μ˜ ν•©μ§‘ν•©μœΌλ‘œ λ³Ό 수 μžˆλ‹€.

union
union
μœ„μ˜ μ½”λ“œκ°€ μ—λŸ¬κ°€ λ‚œ μ΄μœ λŠ” toUppserCaseλŠ” string만이 κ°€μ§€λŠ” λ©”μ†Œλ“œμΈλ° number|string은 가지고 μžˆμ§€ μ•ŠκΈ° λ•Œλ¬Έμ΄λ‹€. μ΄λŸ¬ν•œ νƒ€μž…μ—λŸ¬λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄μ„œλŠ” μΈμžμ— λŒ€ν•œ νƒ€μž…μ„ μ’ν˜€μ€ŒμœΌλ‘œμ¨ ν•΄κ²°ν•  수 μžˆλ‹€.

function printId(id: number | string) {
  if (typeof id === "string") {
    // In this branch, id is of type 'string'
    console.log(id.toUpperCase());
  } else {
    // Here, id is of type 'number'
    console.log(id);
  }
}

Type Alias

Type AliasλŠ” μš°λ¦¬κ°€ λ³€μˆ˜μ²˜λŸΌ νƒ€μž…μ„ μ›ν•˜λŠ” λŒ€λ‘œ 이름을 μ •ν•˜κ³  μ •μ˜ν•˜λŠ” 방법이닀.

type Point = {
  x: number;
  y: number;
};
 
// Exactly the same as the earlier example
function printCoord(pt: Point) {
  console.log("The coordinate's x value is " + pt.x);
  console.log("The coordinate's y value is " + pt.y);
}
 
printCoord({ x: 100, y: 100 });

Interface

InterfaceλŠ” Object νƒ€μž…μ„ μš°λ¦¬κ°€ μ›ν•˜λŠ”λŒ€λ‘œ μ •μ˜ν•˜κΈ° μœ„ν•œ λ˜λ‹€λ₯Έ 방법이닀.

자주 ν˜Όμš©ν•΄μ„œ μ‚¬μš©λ˜λŠ” 두가지 Type alias와 Interface에 λŒ€ν•΄ 정리해보면 λ‹€μŒκ³Ό 같은 차이점을 가진닀.

  • νƒ€μž…μ€ μƒˆλ‘œμš΄ 속성을 ν™•μž₯ν•  λ•Œ intersection을 μ΄μš©ν•΄μ•Όν•˜κ³  interfaceλŠ” extendsλ₯Ό μ΄μš©ν•œλ‹€.

차이1
차이1

  • νƒ€μž…μ€ 쀑볡이 λΆˆκ°€λŠ₯ν•˜μ§€λ§Œ interfaceλŠ” 쀑볡선언이 κ°€λŠ₯ν•˜λ‹€.

차이1
차이1

각각의 λͺ©μ μ„ μœ„ν•œ 방법듀을 가지기 λ•Œλ¬Έμ— 생각보닀 큰 차이가 μ—†λ‹€κ³  λŠκ»΄μ‘Œλ‹€.

Type Assertion

Object.keys() λ¬Έμ΄λ‚˜ try/catch문으둜 받은 errorλ₯Ό λ‹€λ£¨κ±°λ‚˜ ν• λ•Œ μš°λ¦¬λŠ” unknownνƒ€μž…μ„ λ§ˆμ£Όν•œλ‹€. 이럴 λ•Œ ν•„μš”ν•œ νƒ€μž…μœΌλ‘œ μ’ν˜€μ£Όμ–΄μ•Όν•  κ²½μš°κ°€ ν˜„μ‹€μ μœΌλ‘œ ν•„μš”ν•˜λ‹€. 이럴 λ•Œ μ‚¬μš©ν•  수 μžˆλŠ” 방법이 Type Assertion이닀.

Type assertion이 λ¬΄μ„œμš΄ μ΄μœ λŠ” λŸ°νƒ€μž„μ— μš°λ¦¬κ°€ μ˜ˆμΈ‘ν•œ νƒ€μž…κ³Ό λ‹€λ₯Έ 값이 μ‹€μ œλ‘œ λ“€μ–΄μ˜¬μ§€ λͺ¨λ₯Έλ‹€λŠ” 점 λ•Œλ¬Έμ΄λ‹€. κΌ­ ν•„μš”ν•  λ•Œλ§Œ μ‚¬μš©ν•˜μž.

const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;

Literal Type

값을 μ΄μš©ν•΄μ„œ νƒ€μž…μ„ μ •ν•˜λŠ” λ°©λ²•μœΌλ‘œ νƒ€μž…μ΄ ν•˜λ‚˜μ˜ κ°’μœΌλ‘œ κ³ μ •λ˜κΈ° λ•Œλ¬Έμ— 주둜 Union type으둜 μ—¬λŸ¬κ°€μ§€ 값을 μ΄μš©ν•΄ μ •μ˜ν•œλ‹€.

function printText(s: string, alignment: "left" | "right" | "center") {
  // ...
}
printText("Hello, world", "left");

객체λ₯Ό μ΄μš©ν•  λ•ŒλŠ” κ·Έ 값이 κ°€μ§€λŠ” νƒ€μž…μœΌλ‘œ 속성을 νƒ€μž…μ„ μ •μ˜ν•˜μ§€ κ°’μœΌλ‘œ μ •μ˜ν•˜μ§€ μ•ŠλŠ”λ‹€.

literal
literal

μœ„ μ½”λ“œκ°€ μ—λŸ¬κ°€ λ‚œ μ΄μœ λŠ” method의 νƒ€μž…μ΄ "GET"|"POST" κ°’μ˜ union νƒ€μž…μœΌλ‘œ μ •μ˜λ˜μ–΄μžˆλŠ”λ° req의 methodλŠ” "GET"κ°’μœΌλ‘œ νƒ€μž…μ΄ μΆ”λ‘ λœ 것이 μ•„λ‹ˆλΌ string으둜 μΆ”λ‘ λ˜μ—ˆκΈ° λ•Œλ¬Έμ΄λ‹€.

Nullκ³Ό Undefined

  • strictNullChecks: null을 λ°˜λ“œμ‹œ κ±°λ₯Ό 수 있게 ν•˜λŠ” μ˜΅μ…˜μ΄λ‹€.
  • Non-null Assertion Operator(!): nullκ³Ό undefined이 μ•„λ‹ˆλΌ λ‹¨μ–Έν•˜λŠ” operator둜, 단언이기 λ•Œλ¬Έμ— μ§€μ–‘ν•˜μž.
@Troy
맀일의 μ‹œν–‰μ°©μ˜€λ₯Ό κΈ°λ‘ν•˜λŠ” κ°œλ°œμΌμ§€μž…λ‹ˆλ‹€.