Jake Seo
제이크서 개발 블로그
Jake Seo
전체 방문자
오늘
어제
  • 분류 전체보기 (719)
    • AI 서비스 개발 일기 (3)
    • LLM 개발 일기 (1)
    • ------레거시 (2025.08.23 이전)--.. (0)
    • 백준 문제풀이 (1)
    • 릿코드 문제풀이 (2)
    • 알고리즘 이론 (10)
      • 기본 이론 (2)
      • 배열과 문자열 (8)
    • 데이터베이스 (15)
      • Planet Scale (1)
      • MSSQL (9)
      • 디비 기본 개념 (1)
      • SQLite 직접 만들어보기 (4)
    • 보안 (7)
    • 설계 (1)
    • 네트워크 (17)
      • HTTP (9)
      • OSI Layers (5)
    • 회고 (31)
      • 연간 회고 (2)
      • 주간 회고 (29)
    • 인프라 (52)
      • 도커 (12)
      • AWS (9)
      • 용어 (21)
      • 웹 성능 (1)
      • 대규모 서비스를 지탱하는 기술 (9)
    • 깃 (7)
    • 빌드 도구 (7)
      • 메이븐 (6)
      • 그레이들 (0)
    • Java (135)
      • 이펙티브 자바 (73)
      • 자바 API (4)
      • 자바 잡지식 (30)
      • 자바 디자인 패턴 (21)
      • 톰캣 (Tomcat) (7)
    • 프레임워크 (64)
      • next.js (14)
      • 스프링 프레임워크 (28)
      • 토비의 스프링 (6)
      • 스프링 부트 (3)
      • JPA (Java Persistence API) (5)
      • Nest.js (8)
    • 프론트엔드 (48)
      • 다크모드 (1)
      • 노드 패키지 관리 매니저 (3)
      • CSS (19)
      • Web API (11)
      • tailwind-css (1)
      • React (5)
      • React 새 공식문서 요약 (1)
      • HTML (Markup Language) (5)
    • 자바스크립트 (108)
      • 모던 자바스크립트 (31)
      • 개념 (31)
      • 정규표현식 (5)
      • 코드 스니펫 (1)
      • 라이브러리 (6)
      • 인터뷰 (24)
      • 웹개발자를 위한 자바스크립트의 모든 것 (6)
      • 팁 (2)
    • Typescript (49)
    • 리눅스와 유닉스 (10)
    • Computer Science (1)
      • Compiler (1)
    • IDE (3)
      • VSCODE (1)
      • IntelliJ (2)
    • 세미나 & 컨퍼런스 (1)
    • 용어 (개발용어) (16)
      • 함수형 프로그래밍 용어들 (1)
    • ORM (2)
      • Prisma (2)
    • NODEJS (2)
    • cypress (1)
    • 리액트 네이티브 (React Native) (31)
    • 러스트 (Rust) (15)
    • 코틀린 (Kotlin) (4)
      • 자바에서 코틀린으로 (4)
    • 정규표현식 (3)
    • 구글 애널리틱스 (GA) (1)
    • SEO (2)
    • UML (2)
    • 맛탐험 (2)
    • 리팩토링 (1)
    • 서평 (2)
    • 소프트웨어 공학 (18)
      • 테스팅 (16)
      • 개발 프로세스 (1)
    • 교육학 (1)
    • 삶의 지혜, 통찰 (1)
    • Chat GPT (2)
    • 쉘스크립트 (1)
    • 컴파일 (2)
    • Dart (12)
    • 코드팩토리의 플러터 프로그래밍 (4)
    • 플러터 (17)
    • 안드로이드 스튜디오 (1)
    • 윈도우즈 (1)
    • 잡다한 백엔드 지식 (1)
    • 디자인 패턴 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • Javadoc 자바독 자바주석 주석 Comment
  • Pre-rendering
  • 참조 해제
  • 작업기억공간
  • 메이븐 골
  • 추상 팩터리 패턴
  • 느린 쿼리
  • try-with-resources
  • 자바스크립트 인터뷰
  • 자바스크립트 면접
  • 메이븐 라이프사이클
  • item9
  • NEXT JS
  • 메이븐 페이즈
  • 자바 검증
  • 이펙티브 자바 item9
  • 자바스크립트
  • 도커공식문서
  • 러스트
  • 빈 검증
  • 이펙티브자바
  • 외래키 제약조건
  • 팩터리 메서드 패턴
  • 서버리스 컴퓨팅
  • 싱글톤 패턴
  • 자바
  • 싱글톤
  • item7
  • serverless computing
  • 객체복사
  • 디자인패턴
  • 슬로우 쿼리
  • next js app
  • pnpm
  • Next.js
  • bean Validation
  • item8
  • 자바 디자인패턴
  • prerendering
  • 프로그래머의 뇌
  • MSSQL
  • 토비의 스프링
  • rust
  • 스프링 검증
  • 자료구조
  • 플라이웨이트패턴
  • Java
  • 싱글턴
  • 이펙티브 자바
  • 알고리즘

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Jake Seo

제이크서 개발 블로그

Typescript

TS007. 타입스크립트 Union 이란?

2023. 12. 28. 02:03

유니온 (Union) 이란?

  • 타입스크립트에서 타입을 병합할 수 있는 방법 중 하나임
  • | 기호를 이용함
  • 아래의 코드에서 StringOrNumberType 은 string 이나 number 타입 두가지를 병합한 타입임
  • 타입에 유연성을 제공함
type StringOrNumberType = string | number;

let stringOrNumberType: StringOrNumberType = "김모씨";
stringOrNumberType = 100;

타입 가딩 (Type Guarding) 이용

  • Union 타입을 이용하는 경우 아래와 같이 instnaceof 혹은 typeof 를 통한 타입 가딩을 이용해 동작 방식을 지정해줄 수 있음
function combine(input1: number | string, input2: number | string) {
  if (typeof input1 === "number" && typeof input2 === "number") {
    return input1 + input2;
  } else {
    return input1.toString() + input2.toString();
  }
}

const combinedNumbers = combine(1, 5); // returns 6
const combinedStrings = combine("Hello, ", "world!"); // returns "Hello, world!"

유니온 타입 예제

  • 몇가지든 추가 가능함
type StringOrNumberOrBooleanType = string | number | boolean;
type AsyncState = "REQUEST" | "LOADING" | "DONE" | "ERROR";
let state: AsyncState = "DONE"; // 정상 작동
state = "FINISH"; // 에러 `AsyncState` 타입에 없으므로 할당할 수 없는 값

리스트의 유니온 (Union List)

  • 리스트 타입도 유니온 타입을 이용하는 것이 가능함
  • 단, 표기상 몇가지 헷갈리는 점을 잘 알아둬야 함
  • string[] | number[] 와 (string | number)[] 의 차이를 잘 이해해야 한다.

string[] | number[] 이해하기

// string 으로 구성된 list 혹은 number 으로 구성된 list
type StringListOrNumberList = string[] | number[];
// 문자열로 된 리스트 혹은 number 으로 된 리스트만 가능하다.
let list1: StringListOrNumberList = ["a", "b", "c"];
// 두개를 같이 넣으면 에러 난다.
let list2: StringListOrNumberList = ["a", "b", "c", 3]; // 에러

(string | number)[] 이해하기

// 이 경우엔 string 혹은 number 원소를 가진 리스트 표현이 가능하다.
type StringOrBooleanList = (string | number)[];
let list3: StringOrBooleanList = ["a", "b", "c", 3]; // 정상

유니온을 통해 인터페이스 결합하기

  • 자바스크립트에서 기본으로 지원하는 Primitive 타입 외에도 인터페이스로 정의한 것도 Union 으로 결합이 가능하다.
  • 아래의 코드 예제는 Animal 과 Human 인터페이스를 결합한 예시를 보여준다.
  • 두 인터페이스가 결합된 AnimalOrHuman 타입을 변수에 이용하면, 타입스크립트는 오브젝트 내부의 프로퍼티 값을 보고 해당 변수가 Animal 타입인지 Human 타입인지 유추해낸다.
    • 그리고 반드시 둘 중 하나의 타입으로 유추 가능해야 한다.
type Sex = "male" | "female";

interface Animal {
  name: string;
  sex: Sex;
}

interface Human {
  name: string;
  sex: Sex;
  phone: string;
}

type AnimalOrHuman = Animal | Human;

let human1: AnimalOrHuman = {
  name: "김똘똘",
  sex: "male",
  phone: "010",
};

// Human 에게만 있는 phone 속성 값이 있으므로 타입스크립트는 이를 Human 이라고 유추 가능
console.log(human1);

let animal1: AnimalOrHuman = {
  name: "닭",
  sex: "female",
};

// Human 에게만 있는 phone 속성 값이 없으므로 타입스크립트는 이를 Animal 이라고 유추 가능
console.log(animal1);
// 이미 Animal 타입으로 추론했기 때문에 phone 속성이 없다고 여겨져 Human 타입에만 있는 phone 속성을 불러오려 하면 에러가 남
console.log(animal1.phone);

picture 0

마우스를 올려서 추론된 타입을 확인해본 모습

타입 추상화를 잘 해야 하는 이유

  • 사실 interface 나 type 등으로 타입 추상화를 하지 않고 그냥 오브젝트에 들어갈 것을 {} 로 표현해도 되긴 한다.
  • 근데 그 경우에 에러 메세지를 보고 해당 타입이 왜 틀렸는지 디버깅하기 매우 어려워지므로 평소에 타입 추상화를 잘 해두는 것이 좋다.
let animalOrHuman:
  | {
      name: string;
      sex: Sex;
    }
  | {
      name: string;
      sex: Sex;
      phone: string;
    } = {
  name: "김똘일",
  sex: "male",
};

console.log(animalOrHuman);
console.log(animalOrHuman.phone); // 에러, name 과 sex 밖에 정의하지 않았으므로 위의 타입으로 추론되었을 것이다.

picture 1

실제 에러 메세지

let animalOrHuman2: Animal | Human = {
  name: "김똘일",
  sex: "male",
};

console.log(animalOrHuman);
console.log(animalOrHuman.phone); // 에러, 간단한 에러 메세지

picture 2

'phone' does not exists on type 'Animal' 이라고 알려줌으로써 파악하기가 더 쉽다.
'Animal' 타입에 'phone' 이란 프로퍼티는 없구나 하고 인식할 수 있다.

Union 은 n 개의 OR 중 하나의 타입만 만족하면 그 이후에는 어떻게 해도 된다.

  • union 은 n 개의 타입 중 하나만 만족하면 그 이후에는 어떻게 해도 된다.
  • 하나의 타입만 만족 후에 다른 타입의 속성 중 하나가 있든 다 있든 없든 상관하지 않는다.
  • 당연히 n 개의 타입을 다 만족해도 된다.
  • 근데 하나의 타입도 만족하지 못하는 경우엔 에러가 난다.
interface Person {
  name: string;
  age: number;
}

type DeveloperMajor = "backend" | "frontend" | "devops";

interface Developer {
  developerMajor: DeveloperMajor;
  workExperience: number;
}

type PersonOrDeveloper = Person | Developer;

let jake: PersonOrDeveloper = {
  name: "jake",
  age: 20,
};

let jake2: PersonOrDeveloper = {
  name: "jake",
  age: 20,
  workExperience: 5,
};

let jake3: PersonOrDeveloper = {
  name: "jake",
  age: 20,
  workExperience: 5,
  developerMajor: "backend",
};

// Person 혹은 Developer 둘 다 만족하지 못하는 경우엔 에러가 남
// 둘 중에 하나라도 만족하는 것은 에러나지 않음
// 하나를 만족한 이후에 추가적인 다른 1개의 속성을 갖는 것도 에러나지 않음
// 둘 다 만족하는 것도 에러나지 않음
// 무조건 두개의 타입 중 하나라도 만족해야 함
let jake4: PersonOrDeveloper = {
  name: "jake",
  workExperience: 5,
};
저작자표시 비영리 (새창열림)

'Typescript' 카테고리의 다른 글

TS009. 타입스크립트의 내로잉 (Narrowing) 이란?  (0) 2023.12.28
TS008. Typescript Intersection 이란?  (0) 2023.12.28
TS006. 타입스크립트 타입 캐스팅 및 주의점  (0) 2023.12.27
TS005. 타입스크립트의 타입 추론 (type inference)  (0) 2023.12.27
TS004. 타입스크립트의 Enum 타입 간단하게 알아보기  (0) 2023.12.27
    'Typescript' 카테고리의 다른 글
    • TS009. 타입스크립트의 내로잉 (Narrowing) 이란?
    • TS008. Typescript Intersection 이란?
    • TS006. 타입스크립트 타입 캐스팅 및 주의점
    • TS005. 타입스크립트의 타입 추론 (type inference)
    Jake Seo
    Jake Seo
    ✔ 댓글로 틀린 부분을 지적해주시면 기분 나빠하지 않고 수정합니다. ✔ 많은 퇴고를 거친 글이 좋은 글이 된다고 생각합니다. ✔ 간결하고 명료하게 사람들을 이해 시키는 것을 목표로 합니다.

    티스토리툴바