TypeScript. 타입 종류(Union & Literal)

cm·2024년 1월 24일

타입스크립트

목록 보기
4/9

타입 종류(Union & Literal)

1. 유니언 타입

  • 두개 이상의 타입을 허용하는 방법이다.
  • 두개 이상의 타입들 중 어느 하나의 타입에 값 할당이 가능하면 되고 그외의 타입을 가진 값을 할당하려고 하면 타입오류를 발생시킨다.

1-1. 정의 방법 : | (순서무관)

1-2. 내로잉 : 여러 타입 중 특정 타입으로 좁히는 과정

// 값 할당을 이용한 내로잉
let result = number | string;
result = 10; // number
// 조건문을 통한 내로잉
let scientist = Math.random() > 0.5 ? "Kim" : undefined;
if (scientist === "Kim") {
  // string 
}
// 논리연산자를 이용한 내로잉
let scientist = Math.random() > 0.5 && "Kim";
// scientist의 타입은 string | false
if (scientist) {
  scientist.toUpperCase(); // string
} else {
  scientist; // false | string
}

🔥 주의
Math.random() 결과가 0.5이상이면 scientist는 "Kim", 0.5 이하면 false가 반환된다. 즉, scientist의 타입은 string | false이다. 조건문 if(scientist)에서 scientist이 참인 경우는 string | false 중 string만 해당되어 string인 scientist가 블록에 들어오겠지만, scientist가 거짓인 경우, string | false 중 모두가 해당되기 때문에 모두 블록에 들어온다. string도 else에 해당되는 이유는 string에는 ""인 falsy한 값이 있기 때문이다.

// typeof 연산자를 이용한 내로잉
let scientist = Math.random() > 0.5?"Kim" : 10;
if (typeof scientist === string) {}


// 🔺 주의사항 : 객체타입에서는 각각의 속성을 내로잉. 조건문에서 who는 spend 속성타입에 대해서만 내로잉하고 있기 때문에 who.dis를 내로잉한 것이 아니다.(객체 타입 내로잉시 주의!) 
type Member = { spend: number[]; dis: 0.1 };
type Guest = { spend: number };
const member: Member = { spend: [10, 20], dis: 0.1 };
const guest: Guest = { spend: 500 };
const who = Math.random() > 0.5 ? member : guest;
let total: number;
if (typeof who.spend !== "number") {
    total = who.spend.reduce((acc, c) => acc + c, 0);
    who.dis; // Error
} else {
    total = who.spend;
}
//  instanceof 연산자를 이용한 내로잉
class Animal {}
class Dog extends Animal {}
function f(animal: Animal) {
    if (animal instanceof Dog) {
    } else {
    }
}
// 사용자 정의 타입가드
let value: number | string;
if (isNumber(value)) {
    } else {
}

let arr: number[] | number;
if (Array.isArray(arr)) {
	} else {
}
// in 연산자를 이용한 내로잉
type circle = { kind: "circle"; radius: number };
type square = { kind: "square"; sideLength: number };
type Shape = circle | square;
function getArea(shape: Shape): number {
    return "radius" in Shape ? Math.PI * shape.radius ** 2 : shape.sideLength ** 2;
}

값할당, 조건문, 논리연산자, typeOf, instanceOf, in, Array.isArray


2. 리터럴 타입

  • 변수가 특정한 원시값을 가져야함을 정의하는 타입이다.
  • 더 넓은 개념의 타입이라고 해도 리터럴에는 할당이 불가하다. 예를 들어, "ongoing" 을 리터럴타입으로 지정했다면, string 타입이라고 할지라도 할당이 불가하다.
  let lifespan: number | "ongoing" | "uncertain";
  lifespan = 89;
  lifespan = "ongoing";
  lifespan = "byron"; // Error : 정해진 값만 가져야 함
  let something = ""; // string 타입
  lifespan = something; // Error : something이 string이라는 더 넓은 개념이라고 해도 더 구체적인 타입에 할당할 수 없음
profile
나를 위한 기록

0개의 댓글