티스토리 뷰
타입 가드(Type Guard): typeof, instanceof, is를 활용한 안전한 타입 좁히기
미니임 2026. 2. 19. 00:56
타입스크립트(TypeScript)에서 가장 중요한 개념 중 하나인 '타입 가드(Type Guard)'에 대한 블로그 게시글을 작성해 드립니다. 이 글은 typeof, instanceof, 그리고 사용자 정의 타입 가드인 is를 중심으로 풍부한 예제와 함께 구성되었습니다.
# 타입 가드(Type Guard): typeof, instanceof, is를 활용한 안전한 타입 좁히기
타입스크립트를 사용하다 보면 유니온 타입(Union Type)을 자주 접하게 됩니다. 여러 타입을 허용함으로써 유연성을 얻지만, 특정 타입에만 존재하는 속성이나 메서드에 접근하려고 할 때 컴파일러가 경고를 보냅니다. 이때 필요한 것이 바로 **'타입 좁히기(Type Narrowing)'**이며, 이를 가능하게 하는 도구가 **'타입 가드(Type Guard)'**입니다.
런타임 환경에서 값의 타입을 확인하고, 그 범위 안에서 안전하게 코드를 작성하는 방법을 알아보겠습니다.
---
## 1. typeof 연산자: 기본 타입 좁히기
`typeof`는 자바스크립트의 기본 연산자로, `string`, `number`, `boolean`, `symbol` 등 기본 자료형(Primitive type)을 구분할 때 가장 간편하게 사용됩니다.
### 예제: 단위 변환 함수
입력값이 숫자인지 문자열인지에 따라 다르게 처리하는 예제입니다.
```typescript
function formatPadding(value: string | number): string {
// typeof를 사용하여 타입을 좁힙니다.
if (typeof value === "number") {
// 이 블록 안에서 value는 'number' 타입으로 추론됩니다.
return `${value}px`;
}
// 이 블록 안에서 value는 자동으로 'string' 타입으로 추론됩니다.
return value.trim();
}
console.log(formatPadding(20)); // "20px"
console.log(formatPadding(" 10rem ")); // "10rem"
주의사항: typeof는 null이나 배열을 object로 반환하기 때문에, 객체 내부 구조를 파악할 때는 적합하지 않습니다.
2. instanceof 연산자: 클래스 인스턴스 확인
instanceof는 생성자의 prototype 속성이 객체의 프로토타입 체인 어딘가에 존재하는지 확인합니다. 주로 클래스 기반의 객체 지향 프로그래밍에서 특정 클래스의 인스턴스인지 확인할 때 유용합니다.
예제: 알림 시스템
다양한 알림 클래스가 있을 때 각 클래스의 특화된 메서드를 호출하는 예제입니다.
class Email {
sendEmail() {
console.log("이메일을 발송합니다.");
}
}
class SMS {
sendSMS() {
console.log("문자 메시지를 발송합니다.");
}
}
function sendNotification(service: Email | SMS) {
if (service instanceof Email) {
// service가 Email 클래스의 인스턴스임이 보장됩니다.
service.sendEmail();
} else {
// service는 SMS 타입으로 좁혀집니다.
service.sendSMS();
}
}
sendNotification(new Email());
3. 사용자 정의 타입 가드: is 키워드
인터페이스(Interface)는 런타임에 존재하지 않습니다. 따라서 typeof나 instanceof로는 인터페이스 타입을 구분할 수 없습니다. 이때 사용하는 것이 **타입 술어(Type Predicate)**인 is를 활용한 사용자 정의 함수입니다.
함수의 반환 타입을 variable is Type 형태로 정의하면, 해당 함수가 true를 반환할 때 타입스크립트는 그 변수를 해당 타입으로 간주합니다.
예제: API 응답 처리
성공과 실패 응답이 서로 다른 인터페이스를 가질 때의 처리 방식입니다.
interface SuccessResponse {
status: 'success';
data: string[];
}
interface ErrorResponse {
status: 'error';
message: string;
}
// 사용자 정의 타입 가드 함수
function isSuccessResponse(response: SuccessResponse | ErrorResponse): response is SuccessResponse {
return response.status === 'success';
}
function processResponse(response: SuccessResponse | ErrorResponse) {
if (isSuccessResponse(response)) {
// 이 안에서 response는 SuccessResponse 타입입니다.
console.log("데이터 개수:", response.data.length);
} else {
// 이 안에서 response는 자동으로 ErrorResponse 타입이 됩니다.
console.error("에러 메시지:", response.message);
}
}
4. 복합적인 예제: 데이터 필터링
실무에서는 배열 내의 유효하지 않은 값(null, undefined)을 제거하고 타입을 정제할 때 타입 가드를 자주 활용합니다.
function isNotNull<T>(value: T | null | undefined): value is T {
return value !== null && value !== undefined;
}
const mixedValues: (string | null)[] = ["Apple", null, "Banana", null, "Cherry"];
// 타입 가드를 적용하지 않으면 string[] 타입으로 할당할 수 없습니다.
const validFruits: string[] = mixedValues.filter(isNotNull);
console.log(validFruits); // ["Apple", "Banana", "Cherry"]
요약
안전한 타입스크립트 코드를 작성하기 위해 상황에 맞는 타입 가드를 선택하세요.
- typeof: 문자열, 숫자 등 기본 자료형을 확인할 때.
- instanceof: 클래스로 생성된 객체를 구분할 때.
- is (사용자 정의): 인터페이스나 복합적인 로직으로 타입을 좁혀야 할 때.
타입 가드를 적절히 활용하면 불필요한 타입 단언(as)을 줄일 수 있으며, 런타임 에러를 방지하고 가독성 높은 코드를 완성할 수 있습니다.
타입 가드의 개념부터 실무에서 활용하기 좋은 예제들까지 포함하여 게시글을 작성했습니다. 도움 되시길 바랍니다. 추가적으로 궁금한 점이나 수정이 필요한 부분이 있다면 알려주세요.
'Frontend > Typescript' 카테고리의 다른 글
| TypeScript 객체지향 마스터하기: 인터페이스와 클래스를 활용한 추상화 구현 (0) | 2026.02.19 |
|---|---|
| TypeScript 열거형(Enum) vs const 객체: 성능과 가독성 측면에서의 비교 분석 (0) | 2026.02.19 |
| 유니온(Union)과 인터섹션(Intersection): 타입을 유연하게 조합하는 아키텍처 (0) | 2026.02.19 |
| 제네릭(Generics) 완벽 가이드: 유연하고 안전한 코드를 위한 마법 같은 도구 (0) | 2026.02.19 |
| 안전한 코딩을 위한 필수 코스: 함수 타이핑 (매개변수, 반환 타입, 옵셔널 파라미터) (0) | 2026.02.19 |
- Total
- Today
- Yesterday
- SSR
- HTML
- MSA
- 멀티모달
- AI
- CSR
- 스마트안경
- java
- LLM
- 엣지컴퓨팅
- react
- 웹기초
- HBM
- prompt engineering
- 구글
- CSS
- 카카오
- TypeScript
- 협력
- sLLM
- on-device ai
- Javascript
- It용어
- Rag
- Nextjs
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |