TS_타입추론, 타입단언, 타입 좁히기, 서로소 유니온 타입

sunjin·2023년 12월 17일

Typescript

목록 보기
2/5
post-thumbnail

🌿 타입추론

타입이 정의되어 있지 않은 변수의 타입을 자동으로 추론하는 기능

let a = 10;
// number 타입으로 추론
function func(param){ // 오류
}
  • 함수의 매개변수 타입은 자동으로 추론할 수 없다. 타입 추론이 불가능한 변수에는 암시적으로 any 타입이 추론된다.

🌱 타입 추론이 가능한 상황

1. 변수 선언

let b = "hello" //string

let c = {
  id: 1,
  profile : {
    nickname: "badajinsee"
  },
}; 

문제 없이 잘 추론 된다.

2. 구조 분해 할당

let { one, two, three } = [1, "hello", true]

3. 함수의 반환값

function func() {
  return "hello";
} //string

반환값 타입은 return 문을 기준으로 추론된다.

4. 기본값이 설정된 매개변수

function func(message = "bye") {
  return "bye";
}

🌿 타입단언

값 as 타입 으로 특정 값을 원하는 타입으로 단언할 수 있다. 이를 타입 단언 이라고 부른다.

type Person = {
  name: string;
  age: number;
};

let person = {} as Person;
person.name = "한";
person.age = 27;
type Dog = {
  name: string;
  color: string;
};

let dog: Dog = {
  name: "돌돌이",
  color: "brown",
  breed: "진도",
} as Dog;

breed 라는 초과 프로퍼티가 존재하지만 이 값을 Dog 타입으로 단언하여 초과 프로퍼티 검사를 피할수 있다.

🌱 타입 단언의 조건

  • 값 as 단언 <- 단언식
  • A as B
  • A가 B의 슈퍼타입이거나
  • A가 B의 서브타입이어야 함
let num1 = 10 as never;
let num2 = 10 as unknown;

let num3 = 10 as unknown as string; //되도록 쓰지 말기

num 처럼 값을 이렇게 슈퍼-서브 관계를 갖지 않는 타입으로 단언하면 오류가 발생할 확률이 매우 높아진다.

🌱 const 단언

특정 값을 const 타입으로 단언하여 변수를 const로 선언한것과 같이 타입이 변경 된다.

let num4 = 10 as const;

let cat = {
  name: "야옹이",
  color: "yellow",
} as const; // readonly

🌱 Non Null 단언

값 as 타입 형태를 따르지 않는 단언, 값 뒤에 '!'를 붙여주면 undefined이거나 null이 아닐것으로 단언 가능하다.

type Post = {
  title: string;
  author?: string;
};

let post: Post = {
  title: "게시글1",
  author: "한",
};

const len: number = post.author!.length;

🌿 타입좁히기

조건문 등을 이용해 넓은 타입에서 좁은 타입으로 타입을 상황에 따라 좁히는 방법을 이야기 한다.

type Person = {
  name: string;
  age: number;
};

//value => number : toFixed
//value => string : toUpperCase
//value => Date : getTime
//value => Person : name은 age살 입니다.

// instanceof 타입가드
// 내장 클래스 타입을 보장할 수 있는 타입 가드를 만들 수 있다. 
// 그치만 내장 클래스 또는 직접 만든 클래스에만 사용이 가능한 연산 

function func(value: number | string | Date | null) {
  if (typeof value === "number") {
    console.log(value.toFixed());
  } else if (typeof value === "string") {
    console.log(value.toUpperCase());
  } else if (value instanceof Date) {
    console.log(value.getTime());
  }
}

// in 타입 가드 
// 직접 만든 타입과 함께 사용하려면 in 연산자를 이용해야 한다.

function func(value: number | string | Date | null | Person) {
  if (typeof value === "number") {
    console.log(value.toFixed());
  } else if (typeof value === "string") {
    console.log(value.toUpperCase());
  } else if (value instanceof Date) {
    console.log(value.getTime());
  } else if (value && "age" in value) {
    console.log(`${value.name}${value.age}살 입니다`)
  }
}

🌿 서로소 유니온 타입

교집합이 없는 타입들로만 만든 유니온 타입을 말한다.

type Admin = {
  tag: "ADMIN";
  name: string;
  kickCount: number;
};

type Member = {
  tag: "MEMBER";
  name: string;
  point: number;
};

type Guest = {
  tag: "GUEST";
  name: string;
  visitCount: number;
};

type User = Admin | Member | Guest;

함수의 타입가드를 직관적으로 수정할 수 있게 된다.


// Admin => {name}님 현재까지 {kickCount}명 강퇴했습니다.
// Member => {name}님 현재까지 {point}모았습니다.
// Guser => {name}님 현재까지 {visitCount}번 오셨습니다.

function login(user: User) {
  if (user.tag === "ADMIN") {
    console.log(`${user.name}님 현재까지 ${user.kickCount}명 추방했습니다`);
  } else if (user.tag === "MEMBER") {
    console.log(`${user.name}님 현재까지 ${user.point}모았습니다`);
  } else {
    console.log(`${user.name}님 현재까지 ${user.visitCount}번 오셨습니다`);
  }
}

//swith문 사용 

function login(user: User) {
  switch (user.tag) {
    case "ADMIN":
      {
        console.log(
          `${user.name}님 현재까지 ${user.kickCount}명 강퇴했습니다.`
        );
      }
      break;
    case "MEMBER":
      {
        console.log(`${user.name}님 현재까지 ${user.point}모았습니다.`);
      }
      break;
    case "GUEST": {
      console.log(
        `${user.name}님 현재까지 ${user.visitCount}번 방문하셨습니다.`
      );
      break;
    }
  }
profile
🍀

2개의 댓글

comment-user-thumbnail
2023년 12월 18일

저도 알려주세요

1개의 답글