📑 목차
타입스크립트를 사용하다 보면, 컴파일러보다 개발자인 내가 해당 변수의 타입을 더 잘 알고 있는 경우가 있다. 이럴 때 컴파일러에게 "이 변수의 타입은 내가 확신하니까 내 말대로 처리해!"라고 명령하는 것이 바로 타입 단언(Type Assertion) 이다.
1. 타입 단언이란? (as)
변수를 선언할 때는 빈 객체로 두고 싶지만, 실제로는 특정 인터페이스나 타입의 규칙을 따르고 싶을 때가 있다.
type Person = {
name: string;
age: number;
};
// ❌ 에러 발생: 빈 객체는 Person 타입이 아님
// let person: Person = {};
// ✅ 타입 단언 사용
let person = {} as Person;
person.name = "조태민";
person.age = 25;
타입스크립트 컴파일러는 빈 객체 {}를 Person 타입으로 보지 않지만, as Person을 붙여주면 "이건 Person 타입이야"라고 단언하게 되어 에러가 사라진다 .
초과 프로퍼티 검사 회피
객체 리터럴을 직접 할당할 때 발생하는 '초과 프로퍼티 검사'도 타입 단언으로 피할 수 있다 .
type Dog = {
name: string;
color: string;
};
let dog = {
name: "깨갱이",
color: "brown",
breed: "리트리버", // 원래라면 에러 발생 (초과 프로퍼티)
} as Dog; // ✅ 단언으로 해결
2. 타입 단언의 조건
하지만 아무 타입이나 막무가내로 단언할 수 있는 것은 아니다. A as B로 단언하려면 아래 두 조건 중 하나를 반드시 만족해야 한다 .
- A가 B의 슈퍼 타입이다. (A > B)
- A가 B의 서브 타입이다. (A < B)
즉, 두 타입이 서로 포함 관계(교집합) 가 있어야 한다.
let num1 = 10 as never; // ✅ OK (never는 모든 타입의 서브 타입)
let num2 = 10 as unknown; // ✅ OK (unknown은 모든 타입의 슈퍼 타입)
// ❌ Error: number와 string은 겹치는게 없음
// let num3 = 10 as string;
number와 string은 서로소 집합(공통점이 없음)이므로, 서로 단언할 수 없다 .
3. 다중 단언 (눈속임)
만약 억지로라도 number를 string으로 단언하고 싶다면 어떻게 해야 할까?
다중 단언을 이용하면 가능하다.
let num3 = 10 as unknown as string;
- 1단계:
10->unknown(업캐스팅, 가능) - 2단계:
unknown->string(다운캐스팅, 가능)
중간에 만능 타입인 unknown을 끼워 넣어서 컴파일러의 눈을 속이는 방식이다.
하지만 이는 실제 값을 바꾸는 것이 아니라 컴파일러의 눈만 가리는 '눈속임'에 불과하므로, 런타임 에러가 발생할 확률이 매우 높다. 정말 어쩔 수 없는 상황이 아니라면 사용을 지양해야 한다 .
4. const 단언 (as const)
as const는 타입 단언에서만 쓸 수 있는 특별한 문법이다. 이를 사용하면 변수를 마치 const로 선언한 것처럼 타입을 아주 좁게 추론한다.
let num4 = 10 as const;
// 타입이 number가 아닌 리터럴 타입 '10'으로 단언됨
let cat = {
name: "골골이",
color: "yellow",
} as const;
// 모든 프로퍼티가 readonly(읽기 전용)가 됨
객체에 as const를 붙이면 모든 프로퍼티가 readonly가 되어, 의도치 않은 값 변경을 막는 데 유용하다 .
5. Non-null 단언 (!)
null이나 undefined가 아님을 확신할 때 사용하는 단언이다. 값 뒤에 느낌표(!)를 붙여 사용한다 .
type Post = {
title: string;
author?: string; // 선택적 프로퍼티 (string | undefined)
};
let post: Post = {
title: "게시글1",
};
// ❌ 에러: author가 undefined일 수 있음
// const len: number = post.author.length;
// ✅ 해결: author는 절대 null/undefined가 아니라고 단언 (!)
const len: number = post.author!.length;
요약
- 타입 단언 (
as): 컴파일러에게 특정 값의 타입을 강제로 지정한다. - 조건: 두 타입이 슈퍼-서브 관계(교집합)가 있어야 한다.
- 다중 단언:
as unknown as Type으로 강제 단언이 가능하지만 위험하다. - const 단언: 값을 리터럴 타입으로 만들거나 객체를 읽기 전용으로 만든다.
- Non-null 단언 (
!): 값이null이나undefined가 아님을 보장한다.
