가변성(variance)은 타입 시스템에서 매우 중요한 개념 중 하나입니다. 가변성 문제는 타입 안정성을 유지하면서 서로 다른 타입의 데이터를 다루는 과정에서 발생할 수 있습니다. TypeScript와 같은 정적 타입 언어에서는 이 문제를 타입 가드(type guard)를 통해 처리할 수 있습니다.
가변성 문제란 무엇인가요?
가변성 문제는 주로 객체 지향 언어에서 발생하는데, 다음과 같은 상황에서 발생할 수 있습니다.
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
}
class Dog extends Animal {
woof() {
console.log('Woof!');
}
}
class Cat extends Animal {
meow() {
console.log('Meow!');
}
}
function finishWork(animal: Animal) {
if (animal instanceof Dog) {
animal.woof(); // Error: 'woof' does not exist on type 'Animal'
} else if (animal instanceof Cat) {
animal.meow(); // Error: 'meow' does not exist on type 'Animal'
}
}
위 예시에서 finishWork 함수는 Dog나 Cat 객체를 입력으로 받아서 각 동물의 특정 행동을 수행하려고 시도합니다. 그러나 TypeScript 컴파일러는 해당 메소드가 Animal 타입에 존재하지 않는다고 에러를 발생시킵니다.
타입 가드로 문제 해결하기
이러한 문제를 해결하기 위해 타입 가드를 사용할 수 있습니다. 여러 가지 방법이 있지만, 타입 가드 함수나 instanceof 키워드를 활용하는 방법이 일반적입니다.
function isDog(animal: Animal): animal is Dog {
return (animal as Dog).woof !== undefined;
}
function isCat(animal: Animal): animal is Cat {
return (animal as Cat).meow !== undefined;
}
function finishWork(animal: Animal) {
if (isDog(animal)) {
animal.woof(); // No error
} else if (isCat(animal)) {
animal.meow(); // No error
}
}
위 예시에서 isDog와 isCat 함수는 각각 입력된 Animal 객체가 Dog 타입이나 Cat 타입인지를 확인하여 animal is Dog와 animal is Cat 형태의 타입 가드를 제공합니다.
타입 가드를 사용하여 코드의 가변성 문제를 쉽게 처리할 수 있으며, 코드의 안정성을 높일 수 있습니다.
결론
타입 가드는 TypeScript와 같은 정적 타입 언어에서 가변성 문제를 처리하는 데 매우 유용한 도구입니다. 올바르게 활용하면 코드의 안전성을 높이고 유지보수성을 개선할 수 있습니다.
위의 예시는 TypeScript를 사용하여 작성되었지만, 다른 정적 타입 언어에서도 유사한 개념을 적용할 수 있습니다.
참고 자료
- TypeScript 공식 문서: Type Guards and Differentiating Types
- “Understanding TypeScript” by Maximilian Schwarzmüller, Packt Publishing (2019)
- “Effective TypeScript” by Dan Vanderkam, O’Reilly Media (2019)