deep-dive-everything / typescript-with-react

우아한 타입스크립트 with 리액트 스터디
0 stars 0 forks source link

다음 코드 중 isCat 함수의 리턴 타입을 boolean으로 변경했을 때 발생하는 문제점에 대해 설명해주세요. #15

Closed hotdog1004 closed 1 month ago

hotdog1004 commented 1 month ago

📚 137p - 139p 📌 아래의 코드 중 isCat 함수의 리턴 타입을 boolean으로 변경했을 때 발생하는 문제점에 대해 설명해주세요.

interface Cat {
  meow: number;
  fly: boolean;
}
interface Bird {
  chirp: number;
  fly: boolean;
}

function isCat(animal: Cat | Bird):  animal is Cat {
// isCat 함수의 리턴타입을 boolean으로 변경한다면 어떻게 될까요? 
  if ((animal as Cat).meow) {
    return true; 
  } else {
    return false; 
  }
}

function pet(animal: Cat | Bird) {
  if (isCat(animal)) {
    console.log(animal.meow);
  } else {
    console.log(animal.chirp); 
  }
}
kwonhygge commented 1 month ago

is연산자를 사용하지 않으면 타입스크립트가 animal의 타입이 Cat이라는 것을 추론하지 못해 Cat | Bird라는 유니온타입으로 추론하게 됩니다. 따라서 타입에러가 발생할 수 있습니다. if (isCat(animal)) { console.log(animal.meow); // Error: Property 'meow' does not exist on type 'Cat | Bird' } else { console.log(animal.chirp); //Error: Property 'chirp' does not exist on type 'Cat | Bird' }

frogk commented 1 month ago

is 연산자가 아닌 boolean으로 타입을 변경하는 경우 타입 가드가 없어 pet 함수 내에서 타입 추론이 불가능해 에러가 발생됩니다.

pet 함수 내에서는 Cat | Bird 라는 유니온 타입으로 추론하게 되는데 이 경우 Cat 과 Bird 모두 가지고 있는 속성만 사용할 수 있으므로 어느 하나에만 존재하는 속성을 사용하는 경우 에러가 발생되게 됩니다. 따라서 animal is Cat 과 같이 타입 좁히기를 하는 경우 타입스크립트가 타입 가드를 인식하여 속성에 접근할 수 있게 됩니다.

hotdog1004 commented 1 month ago

예시 코드에서는 is 연산자로 사용자 정의 타입 가드를 만들었습니다. animal is Cat 로 리턴 타입을 지정할 경우 타입스크립트는 이를 통해 animal의 타입을 좁힐 수 있게 됩니다. animal is Catboolean 으로 변경하게 되면 타입스크립트는 animal의 타입을 좁힐 수 없고, animal의 타입은 Cat | Bird 가 됩니다. 결과적으로 animal에는 Cat과 Bird의 교집합인 fly 프로퍼티만 들어갈 수 있게되므로 animal.meow와 animal.chirp를 사용할 경우 에러가 발생합니다.

limejin commented 1 month ago

타입 좁히기가 제대로 작동하지 않아서 pet 함수 내 동물 타입이 Cat인지 Bird인지 안전하게 구분할 수 없게됩니다. 그러면 각 타입에 따른 속성 (meow, chirp) 가 존재하지 않을 수 있다고 판단하여 오류가 발생할 수 있습니다.

samseburn commented 1 month ago

타입 좁히기가 제대로 이루어지지 않습니다.

타입스크립트는 is 연산자를 사용한 animal is Cat과 같은 타입 가드를 통해 조건문 내부에서 타입을 안전하게 좁혀 true일 경우 Cat이라는 타입으로 좁혀주는데, 리턴 타입을 불리언 값으로 변경하면 이러한 기능을 잃게 됩니다.