TypeScript Study(4) - 타입 추론 & 타입 단언 & 타입 가드

김재한·2024년 6월 22일
0

TypeScript 정리

목록 보기
4/8

타입 추론

TypeScript 는 타입이 정의되어있지 않은 변수의 타입을 자동으로 추론해주는 기능이 있다. 😀

이러한 기능으로 모든 변수에 일일이 타입을 정의하지 않아도 돼서 간결한 코드를 만들 수 있다.

어떠한 상황에서 타입 추론이 가능하며, 어떤 원리로 추론을 하는 지에 대해 알아보자❗️

타입 추론이 가능한 상황

☝🏻 변수 선언

변수의 초기값 을 기준으로 타입을 추론한다.

let a = 10; // number 타입으로 추론

let b = "hello"; // string 타입으로 추론

let c = { // id, name, profile, urls 프로퍼티가 있는 객체 타입으로 추론
  id: 1,
  name: "jaehan",
  profile: {
    nickname: "winterlood",
  },
  urls: ["https://velog.io/@jae_han_e/posts"],
};

✌🏻 구조분해 할당

let { id, name, profile } = c; 
// id: number, namme: string, profile: {nickname: string}

let [one, two, three] = [1, "hello", true];
// one: number, two: string, three: boolean

🤟🏻 함수 선언

함수의 return 값 을 기준으로 타입을 추론한다.
param 의 경우 default 값 으로 param의 타입을 추론한다.

function func() { // 반환값이 string 타입으로 추론된다
  return "hello";
}

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

타입단언 ( Type Assertion )

선언한 값이 타입과 맞지 않더라도 as Type 을 통해 타입을 단언해 에러를 해결할 수 있다.

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

let person: Person = {}; // ❌ error!
person.name = "";
person.age = 23;

Person 타입으로 선언된 person 을 빈객체 {} 로 초기화 하고
이후에 값을 넣어주려고 위와 같이 사용하면 에러가 발생한다.
( nameage 는 필수값이기 때문에 error ! )

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

let person = {} as Person; // ✅ OK
person.name = "";
person.age = 23;

이러한 경우에는 빈 객체 {}Person 타입이라고 타입 단언을 해주면 에러가 사라진다.

앞에서 설명한 초과 프로퍼티 에러도 해결할 수 있다.

type Dog = {
  name: string;
  color: string;
};

let dog: Dog = {
  name: "돌돌이",
  color: "brown",
  breed: "진도", // 초과 프로퍼티 ( 원래는 error! )
} as Dog

하지만 모든 경우에서 타입 단언을 사용할 수 있는 것은 아니다.

타입 단언의 규칙

타입 단언의 경우 변수 = Value as Type 문법으로 사용한다.

이 때, Value 가 Type 의 부모타입 이거나 서브타입 인 경우에만 사용이 가능하다.

let num1 = 10 as never;   // ✅
let num2 = 10 as unknown; // ✅

let num3 = 10 as string;  // ❌ error!

never 는 모든 타입의 자식타입이고, unknown 은 모든 타입의 부모타입니다.

타입 가드 ( Type Guard )

Union Type 으로 선언되었을 때, 타입과 맞지 않는 함수를 사용 할 경우 에러가 발생할 수 있다.

function func(value: number | string) {
  // Type이 정해지지 않음
  value.toFixed() // ❌ error!
  value.toUpperCase() // ❌ error!
}

이때 타입 가드 를 사용해서 특정 타입임을 보장해주어야 한다.

typeof , instanceof, in 을 사용해서 타입을 보장하는 방법에 대해 알아보자!

  • typeof A === B : A의 타입이 B인지 확인
  • A instanceof B : A가 B의 요소인지 확인한다.
    • B에는 타입이 오면 안되고 Class 가 와야한다.
  • A in B: A 프로퍼티가 B에 있는지를 확인한다.
    • B에는 null 이나 undefined 값이 들어오면 안된다.
type Person = {
  name: string;
  age: number;
};

function func(value: number | string | Date | null | Person) {
  if (typeof value === "number") {
    // number 타입인 경우에만 실행
    console.log(value.toFixed());
  } else if (typeof value === "string") {
    // string 타입인 경우에만 실행
    console.log(value.toUpperCase());
  } else if (value instanceof Date) {
    //Date 타입인 경우에만 실행
    console.log(value.getTime());
  } else if (value && "age" in value) {
    // value 에 age 프로퍼티가 있는 경우에만 실행.
    // value 는 null or undefined 가 오면 완되므로 'value &&' 추가
    console.log(`${value.name}${value.age}살 입니다`)
  }
}

if(value instanceof Person) 을 사용하지 못하는 이유는 Person 이 Class 가 아닌 Type이기 때문이다.

참고
한 입 크기로 잘라먹는 타입스크립트

0개의 댓글