StudyForYou / ouahhan-typescript-with-react

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

#12 [4장_2] 자바스크립트 연산자를 이용한 3가지의 대표적인 타입가드 연산자와, 사용자 정의 타입가드를 사용하는 연산자에 대해 설명해주세요! #24

Closed hyeyoonS closed 2 months ago

hyeyoonS commented 3 months ago

❓문제

(1) 자바스크립트 연산자를 이용한 3가지의 대표적인 타입가드 연산자( typeof/instanceof/in)와 사용자 정의 타입가드를 사용하는 연산자를 말해주세요! (2) 각각의 연산자 어떤 상황에서 사용이 되는지 간단하게 설명해주세요.

🎯답변

[자바스크립트 연산자를 사용한 타입 가드]

1. typeof 연산자

2. instanceof 연산자

3. in 연산자

[사용자 정의 타입 가드]

summerkimm commented 3 months ago
  1. typeof 연산자

    • 변수의 데이터 타입을 문자열 형태로 반환함
    • 기본 데이터 타입(숫자, 문자열, 불리언, 객체, 함수 등)을 검사하는 데 유용함
    let value = "Hello, World!";
    if (typeof value === "string") {
        console.log("value는 문자열입니다.");
    }
  2. instanceof 연산

    • 객체가 특정 클래스 또는 생성자 함수의 인스턴스인지 검사함
    • 프로토타입 체인을 통해 객체의 타입을 확인함
    class Person {}
    let person = new Person();
    
    if (person instanceof Person) {
        console.log("person은 Person 클래스의 인스턴스입니다.");
    }
  3. in 연산자

    • 객체에 특정 프로퍼티가 존재하는지 확인함
    • 객체의 키를 검사하는 데 사용됨
    let animal = { dog: "mung", cat: "yaong" };
    
    if ("dog" in animal) {
        console.log("animal 객체에 dog 프로퍼티가 존재합니다.");
    }
qooktree1 commented 3 months ago
/** typeof
 * 원시 타입을 좁히는 데 사용한다.
 */

type PrimitiveTypes = number | string;

const test = (param: PrimitiveTypes): string => {
    if (typeof param === "number") {
        return 'isNumber'
    }
    return 'isNaN'
}

/** instanceof
 * 인스턴스화된 객체가 특정 클래스의 인스턴스인지 확인할 때 사용
 */
const onKeyDown = (e: React.KeyboardEvent) => {
    if (e.target instanceof HTMLInputElement && e.key === "Enter") {
        e.target.blur();
    }
}

/** in
 * 객체에 특정 속성이 있는지 확인할 때 사용
 */
interface Circle {
  radius: number;
}

interface Rectangle {
  width: number;
  height: number;
}

type Shape = Circle | Rectangle

function area(shape: Shape): number {
    if ('width' in shape) return shape.width * shape.height;
    return 3.14 * shape.radius ** 2
}

/** 사용자 정의 타입 가드 함수
 * is 연산자를 사용하여 함수의 반환 타입을 특정 조건에 만족할 때 타입 좁히기를 사용한다.
 */
const isDestinationCode = (x: string): x is DestinationCode => destinationCodeList.includes(x);

const getAvailableDestinationNameList = async (): Promise<DestinationName[]> => {
    const data = await AxiosRequest<string[]>("get", ".../destinations");
    const destinationNames: DestinationName[] = [];
    data?.forEach(str => {
        if (isDestinationCode(str)) {
            destinationNames.push(destinationNameSet[str]);
        }
    })
}
hyeyoonS commented 3 months ago

자바스크립트 연산자를 이용한 타입가드 연산자

1. 원시 타입을 추론하는 typeof 연산자

typeof 연산자로 검사할 수 있는 타입 목록

const replaceHyphen: (date: string | Date) => string | Date = (date) => {
    if (typeof date === "string") {
        //이 분기에서는 date의 타입이 string으로 추론된다
        return date.replace(/-/g, "/");
    }

    return date;
};

2) 인스턴스화된 객체 타입을 판별하는 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());
  }
}

3. 객체의 속성여부에 따른 in연산자

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

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 Dog = {
  name: string;
  isBark: boolean;
};

type Cat = {
  name: string;
  isScratch: boolean;
};

type Animal = Dog | Cat;

function warning(animal: Animal) {
  if ("isBark" in animal) {
    console.log(animal.isBark ? "짖습니다" : "안짖어요");
  } else if ("isScratch" in animal) {
    console.log(animal.isScratch ? "할큅니다" : "안할퀴어요");
  }
}

4) 사용자 정의 타입가드를 사용하는 is 연산자

// Dog 타입인지 확인하는 타입 가드
function isDog(animal: Animal): animal is Dog {
  return (animal as Dog).isBark !== undefined;
}

// Cat 타입인지 확인하는 타입가드
function isCat(animal: Animal): animal is Cat {
  return (animal as Cat).isScratch !== undefined;
}

function warning(animal: Animal) {
  if (isDog(animal)) {
    console.log(animal.isBark ? "짖습니다" : "안짖어요");
  } else {
    console.log(animal.isScratch ? "할큅니다" : "안할퀴어요");
  }
}