웹개발/typescript
[타입스크립트] 타입 가드
joamashi
2024. 9. 2. 21:01
더욱 안전하고 명확한 코드를 위한 필수 도구
타입스크립트는 강력한 타입 시스템을 갖춘 언어로, 개발 중에 오류를 조기에 발견하고 코드의 신뢰성을 높이는 데 도움을 줍니다. **타입 가드(Type Guard)**는 이러한 타입 시스템의 핵심 기능 중 하나로, 런타임에 변수의 실제 타입을 검사하여 코드 블록 내에서 더 정확한 타입 추론을 가능하게 합니다.
왜 타입 가드가 필요할까요?
- 유연한 타입 시스템: 타입스크립트는 다양한 타입을 지원하지만, 때로는 여러 타입을 가질 수 있는 변수를 다뤄야 할 때가 있습니다.
- 런타임 오류 방지: 타입 가드를 통해 변수의 타입을 검사하여 예상치 못한 타입으로 인한 오류를 미리 방지할 수 있습니다.
- 코드 가독성 향상: 명확한 타입 검사를 통해 코드의 의도를 명확하게 표현하고 다른 개발자의 이해를 돕습니다.
타입 가드의 종류와 예시
1. typeof 연산자
- 기본 타입 검사: number, string, boolean, undefined, object, function 등의 기본 타입을 검사합니다.
function printValue(value: number | string) {
if (typeof value === 'number') {
console.log(`숫자입니다: ${value}`);
} else if (typeof value === 'string') {
console.log(`문자열입니다: ${value}`);
}
}
2. instanceof 연산자
- 객체의 타입 검사: 특정 클래스의 인스턴스인지 확인합니다.
class Person {}
class Student extends Person {}
function isStudent(person: Person): person is Student {
return person instanceof Student;
}
function greet(person: Person) {
if (isStudent(person)) {
console.log(`학생입니다: ${person.name}`);
} else {
console.log(`일반인입니다.`);
}
}
3. in 연산자
- 인터페이스의 프로퍼티 존재 여부 확인: 특정 인터페이스의 프로퍼티가 존재하는지 확인합니다.
4. 사용자 정의 타입 가드 함수
- 복잡한 조건: 위에서 설명한 연산자들로는 충분하지 않을 때 사용자 정의 함수를 통해 타입 가드를 만들 수 있습니다.
interface Employee {
type: 'fulltime' | 'parttime';
name: string;
salary?: number;
}
function isFulltimeEmployee(employee: Employee): employee is Employee {
return employee.type === 'fulltime';
}
왜 타입 가드를 사용해야 할까요?
- 더 안전한 코드: 런타임 오류를 줄이고 코드의 신뢰성을 높입니다.
- 더 명확한 코드: 코드의 의도를 명확하게 표현하여 유지보수를 쉽게 합니다.
- 더 강력한 타입 시스템: 타입스크립트의 타입 시스템을 최대한 활용하여 더욱 정교한 코드를 작성할 수 있습니다.
1. 타입 가드를 사용하여 배열 요소의 타입을 검사하는 방법
배열 요소의 타입을 검사하려면 forEach, map, filter 등의 배열 메서드를 사용하면서 각 요소에 대해 타입 가드를 적용하면 됩니다.
interface Person {
name: string;
age: number;
}
interface Animal {
name: string;
species: string;
}
function printName(item: Person | Animal) {
if ('age' in item) {
console.log(`Person: ${item.name}, ${item.age}세`);
} else {
console.log(`Animal: ${item.name}, ${item.species}`);
}
}
const mixedArray: (Person | Animal)[] = [
{ name: 'Alice', age: 30 },
{ name: 'Bob', species: 'dog' },
];
mixedArray.forEach(printName);
위 예시에서 'age' in item은 item이 Person 타입인지 확인하는 타입 가드 역할을 합니다.
2. 사용자 정의 타입 가드 작성 예시
더 복잡한 조건을 검사하기 위해 사용자 정의 타입 가드 함수를 만들 수 있습니다.
interface Employee {
type: 'fulltime' | 'parttime';
name: string;
salary?: number;
}
function isFulltimeEmployee(employee: Employee): employee is Employee {
return employee.type === 'fulltime' && employee.salary !== undefined;
}
위 예시에서는 isFulltimeEmployee 함수가 employee가 fulltime 타입이고 salary 프로퍼티가 undefined가 아닌지 확인하는 사용자 정의 타입 가드입니다.
3. 타입 가드와 디스크리미네이트 유니온 타입의 차이점
- 디스크리미네이트 유니온 타입: 유니온 타입에서 각 타입을 구분하기 위해 공통된 프로퍼티를 사용하는 방법입니다. 컴파일러가 자동으로 타입을 추론해줍니다.
- 타입 가드: 런타임에 실제 타입을 검사하여 코드 블록 내에서 더 정확한 타입 추론을 가능하게 합니다.
// 디스크리미네이트 유니온 타입
interface Circle {
kind: 'circle';
radius: number;
}
interface Square {
kind: 'square';
sideLength: number;
}
type Shape = Circle | Square;
function getArea(shape: Shape) {
if (shape.kind === 'circle') { // 컴파일러가 자동으로 타입을 추론
// ...
} else {
// ...
}
}
// 타입 가드
function isCircle(shape: Shape): shape is Circle {
return shape.kind === 'circle';
}
둘의 차이점을 요약하면 다음과 같습니다.
- 디스크리미네이트 유니온 타입: 컴파일 타임에 타입을 구분하고, 컴파일러가 자동으로 타입을 추론합니다.
- 타입 가드: 런타임에 타입을 검사하고, 코드 블록 내에서 더 정확한 타입 추론을 가능하게 합니다.
어떤 것을 사용해야 할까요?
- 디스크리미네이트 유니온 타입: 타입이 명확하게 구분되고 컴파일러가 자동으로 처리해줄 수 있을 때 사용하면 편리합니다.
- 타입 가드: 더 복잡한 조건이나 런타임에 타입이 결정될 때 사용하면 유용합니다.
728x90