[TypeScript] 타입 오퍼레이터

윤지·2024년 11월 18일

TypeScript

목록 보기
4/12
post-thumbnail

| (OR): 유니온 타입

  • 특징: 여러 타입 중 하나의 타입만 만족하면 됨
  • 사용 예시: 하나의 값이 다양한 타입을 가질 수 있을 때 유용함

1. 유니온 타입 예제

기본 타입

let value: number | string | boolean = 10;
value = "hello";
value = true;

객체 타입

let obj: { name: string; age: number } | { skill: string } = {
  name: "Alice",
  age: 30,
};
obj = { skill: "JavaScript" };

배열 타입

let arr: number[] | string[] = [1, 2, 3];
arr = ["apple", "banana", "orange"];

// 혼합 배열: 각 요소가 숫자 또는 문자열
let mixArr: (number | string)[] = ["a", 1, "b"];

2. 유니온 타입의 문제점

유니온 타입은 여러 타입 중 하나를 선택 가능하나, 특정 타입의 메서드 호출 시 타입 추론 불명확으로 에러 발생 가능

⚠️ 문제 예시

function printProcess(value: string | number): string | number {
  return value;
}

// 반환값이 string 또는 number
const value1 = printProcess("hello, world");
const value2 = printProcess(10);

// 이 시점에서 value1과 value2의 타입이 명확하지 않아 에러 발생
console.log(value1.toUpperCase()); // 문자열 메서드
console.log(value2.toFixed(2));    // 숫자 메서드

에러 발생 이유

TypeScript는 value1value2가 각각 string 또는 number 중 어느 타입인지 확실하지 않으므로 메서드 호출을 허용하지 않음


3. 문제 해결 방법

(1) 타입 가드(Type Guard)

타입 가드는 값의 타입을 좁혀 특정 타입임을 명시적으로 알려줌. 이를 통해 안전하게 메서드를 호출할 수 있음

타입 가드 적용 예제

function printProcess(value: string | number): string | number {
  return value;
}

const value1 = printProcess("hello, world");
const value2 = printProcess(10);

// 타입 가드를 사용해 안전하게 메서드 호출
if (typeof value1 === "string") {
  console.log(value1.toUpperCase()); // 문자열일 경우
}

if (typeof value2 === "number") {
  console.log(value2.toFixed(2)); // 숫자일 경우
}

타입 가드로 해결된 이유

  • typeof value1 === "string" 조건: value1string 타입임이 확실하므로, toUpperCase 메서드를 안전하게 호출 가능함
  • typeof value2 === "number" 조건: value2number 타입임이 확실하므로, toFixed 메서드를 안전하게 호출 가능함

(2) 함수 오버로드(Function Overload)

함수 오버로드는 같은 이름의 함수를 여러 가지 매개변수 타입과 반환 타입으로 정의하여, 함수 호출 시 정확한 타입 추론을 가능하게 함

함수 오버로드를 사용하면 코드의 가독성과 타입 안정성을 높일 수 있으나, 모든 가능한 경우의 수를 고려해야 하므로 신중한 사용 필요

함수 오버로드 예제

// 함수 오버로드 시그니처
function combine(a: number, b: number): number;
function combine(a: string, b: number): string;
function combine(a: number, b: string): string;

// 실제 구현
function combine(a: number | string, b: number | string): number | string {
  if (typeof a === "number" && typeof b === "number") return a + b;
  else return `${a}${b}`;
}

// 함수 호출
const result1 = combine(10, 10); // 숫자
console.log(result1.toFixed(2)); // 20.00

const result2 = combine("Hello", 10); // 문자열
console.log(result2.toUpperCase()); // HELLO10

함수 오버로드의 특징

  1. 함수 선언문에서만 사용 가능함
  2. TypeScript 고유의 문법으로, JavaScript에는 존재하지 않음
  3. 구체적인 사용 사례 정의: 함수의 모든 가능한 경우를 명확하게 기술 가능
  4. 실제 구현: 구현부는 모든 매개변수 타입 경우를 처리할 수 있도록 작성 필요

& (AND)인터섹션 타입

  • 특징: 두 타입의 모든 속성을 결합하여 모두 만족해야 하는 타입 생성
  • 사용 예시: 여러 객체 타입을 하나로 합칠 때 유용

기본 사용

let value: { name: string; age: number } & { skill: string } = {
  name: "Alice",
  age: 30,
  skill: "JavaScript",
};

🤔 왜 이렇게 사용하는가?

하나의 객체가 여러 타입의 속성을 모두 가져야 할 때 사용. 예를 들어, 아래처럼 모든 속성을 한 번에 정의할 수도 있으나, 인터섹션 타입은 타입 재사용성과 확장성을 높임

// 모든 속성을 한 번에 정의
let value2: { name: string; age: number; skill: string } = {
  name: "Alice",
  age: 30,
  skill: "JavaScript",
};

any, never 결합

  1. any와 결합

    • any가 포함되면 결과는 항상 any로 평가
    let value: any & { name: string } = { name: "Alice" };
    console.log(value.name); // 정상 동작
  2. never와 결합

    • never가 포함되면 결과는 항상 never로 평가
    let value: never & { name: string };
    // value는 사용할 수 없음

출처: 수코딩

profile
프론트엔드 공부 기록 아카이빙🍁

0개의 댓글