TypeScript - Type Guards: A Beginner's Guide

안녕하세요, 미래의 코딩 슈퍼스타 여러분! ? 저는 TypeScript와 Type Guards의 흥미로운 여정을 안내해 드릴 수 있게 되어 기쁩니다. 컴퓨터 과학을 오랫동안 가르쳐온 사람으로서, Type Guards를 이해하는 것은 TypeScript 대宇宙에서 슈퍼파워를 가지는 것과 같다고 말씀드릴 수 있습니다. 그럼 이제 이 파워를 함께 풀어보겠습니다!

TypeScript - Type Guards

What are Type Guards?

먼저 Type Guards가 무엇인지 이해해 보겠습니다. 상상해 보세요, 고급 파티에서 경비원으로 일하고 있는 당신. 당신의 임무는 각 손님의 초대장을 확인하고 그들이 허용된 구역에 들어갈 수 있는지 확인하는 것입니다. TypeScript의 Type Guards 역시 비슷한 역할을 합니다 - 컴파일러가 특정 코드 블록 내에서 변수의 타입을 확인하고 좁혀내는 데 도움을 줍니다.

이제 오늘 배울 세 가지 주요 Type Guards를 탐구해 보겠습니다:

Type Guard 설명
typeof 변수의 타입을 확인합니다
in 객체에 속성이 존재하는지 확인합니다
instanceof 객체가 특정 클래스의 인스턴스인지 확인합니다

The 'typeof' Type Guard in TypeScript

'typeof' Type Guard는 "너는 무엇인가?"라고 묻는 것과 같습니다. 변수의 타입을 확인하는 데 사용됩니다. 예제를 보겠습니다:

function printAll(strs: string | string[] | null) {
if (typeof strs === "object") {
for (const s of strs) {
console.log(s);
}
} else if (typeof strs === "string") {
console.log(strs);
} else {
// 아무것도 안します
}
}

이 예제에서 우리는 typeof를 사용하여 strs가 객체(배열을 포함)인지 문자열인지 확인하고 있습니다. 객체라면 루프를 돌고, 문자열이라면 직접 출력합니다.

이를 기억하는 재미있는 방법은 이렇습니다: 애완동물 가게에서 동물이 개인지 고양이인지 확인하고 싶을 때, "너는 무엇 종의 동물인가?"라고 물을 수 있습니다. typeof는 TypeScript에서 정확히 이와 같은 역할을 합니다!

The 'in' Type Guard in TypeScript

'in' Type Guard는 "이 기능이 있니?"라고 묻는 것과 같습니다. 객체에 속성이 존재하는지 확인합니다. 예제를 보겠습니다:

type Fish = { swim: () => void };
type Bird = { fly: () => void };

function move(animal: Fish | Bird) {
if ("swim" in animal) {
animal.swim();
} else {
animal.fly();
}
}

이 코드에서 우리는 animalswim 속성이 있는지 확인하고 있습니다. 있다면 Fish라고 가정하고 swim 메서드를 호출하고, 아니라면 Bird라고 가정하고 fly 메서드를 호출합니다.

이를 다음과 같이 생각해 보세요: 새로운 애완동물이 물고기인지 새인지 확인하려면, 그것이 비늘을 가지고 있는지 확인할 수 있습니다. in Type Guard는 바로 이와 같은 특성 속성을 확인합니다.

The 'instanceof' Type Guard in TypeScript

'instanceof' Type Guard는 "이 가족의 일원인가?"라고 묻는 것과 같습니다. 객체가 특정 클래스의 인스턴스인지 확인합니다. 예제를 보겠습니다:

class Bird {
fly() {
console.log("Flying...");
}
}

class Fish {
swim() {
console.log("Swimming...");
}
}

function move(pet: Bird | Fish) {
if (pet instanceof Bird) {
pet.fly();
} else {
pet.swim();
}
}

let myBird = new Bird();
move(myBird); // 출력: Flying...

이 예제에서 우리는 petBird 클래스의 인스턴스인지 확인하고 있습니다. 그렇다면 fly 메서드를 호출하고, 아니라면 Fish라고 가정하고 swim 메서드를 호출합니다.

이를 다음과 같이 생각해 보세요: 가족 모임에서 누군가가 존son 가족의 일원인지 확인하려면, "너는 존son인가?"라고 물을 수 있습니다. instanceof는 TypeScript에서 정확히 이와 같은 역할을 합니다!

Putting It All Together

이제 세 가지 Type Guards를 모두 배웠으므로, 그들을 모두 함께 사용하는 방법을 보겠습니다:

class Car {
drive() { console.log("Vroom!"); }
}

class Bicycle {
ride() { console.log("Pedal!"); }
}

type Vehicle = Car | Bicycle | string;

function useVehicle(vehicle: Vehicle) {
if (typeof vehicle === "string") {
console.log(`The vehicle is: ${vehicle}`);
} else if (vehicle instanceof Car) {
vehicle.drive();
} else if ("ride" in vehicle) {
vehicle.ride();
} else {
console.log("Unknown vehicle type");
}
}

useVehicle("Skateboard");  // 출력: The vehicle is: Skateboard
useVehicle(new Car());     // 출력: Vroom!
useVehicle(new Bicycle()); // 출력: Pedal!

이 예제에서 우리는 세 가지 Type Guards를 모두 사용하고 있습니다:

  1. typeof를 사용하여 차량이 문자열인지 확인합니다.
  2. instanceof를 사용하여 차량이 Car인지 확인합니다.
  3. in을 사용하여 차량이 ride 메서드를 가지고 있는지 확인합니다 (이는 Bicycle를 의미합니다).

이는 마치 수사관이 모든 기술을 사용하여 정확히 어떤 차량인지 파악하는 것과 같습니다!

Conclusion

그렇습니다, 제 코딩 제자 여러분! 우리는 TypeScript Type Guards의 땅을 여행하며, typeof, in, instanceof 가드를 탐구했습니다. 이 강력한 도구들은 TypeScript가 당신의 의도를 더 잘 이해할 수 있도록 해주어 더 안전하고 예측 가능한 코드를 작성하는 데 도움이 될 것입니다.

기억하세요, Type Guards를 사용하는 것은 코드와 친절한 대화를 나누는 것과 같습니다. 코드를 더 잘 이해하기 위해 질문하는 것입니다. 그ذا서 다음 번에 코딩을 할 때, 이 Type Guards를 사용하여 변수와 대화를 나누지 않도록 하세요!

계속 연습하고, 호기심을 가지고 있으면, 당신은 곧 Type Guards를 마스터할 것입니다. 다음 번에 만날 때까지, 행복한 코딩을 하세요! ??

Credits: Image by storyset