타입 단언(Type Assertion)은 개발자가 TypeScript에게 "이 값의 타입은 내가 알고 있어"라고 알려주는 것 입니다. 타입을 변환하는 게 아닙니다.

as 키워드

TYPESCRIPT
// DOM 요소 가져올 때 가장 많이 사용
const input = document.getElementById('username');
// input: HTMLElement | null

// as로 더 구체적인 타입을 단언
const inputEl = document.getElementById('username') as HTMLInputElement;
inputEl.value = '홍길동'; // OK — HTMLInputElement의 속성에 접근 가능

앵글 브래킷 문법 (JSX에서 사용 불가)

TYPESCRIPT
// 앵글 브래킷 문법 — JSX 파일(.tsx)에서는 사용 불가
const inputEl = <HTMLInputElement>document.getElementById('username');

// TSX에서는 반드시 as를 사용
const inputEl2 = document.getElementById('username') as HTMLInputElement;

React/Next.js 프로젝트에서는 항상 as를 쓰므로, as 문법만 익히면 됩니다.

타입 단언의 제약

TypeScript는 말도 안 되는 단언 은 막아 줍니다.

TYPESCRIPT
// ❌ string을 number로 단언 불가
// const value = 'hello' as number; // Error

// 두 타입 사이에 충분한 관련성이 있어야 단언 가능
const value = 'hello' as string;       // OK (동일 타입)
const elem = document.createElement('div') as HTMLDivElement; // OK (상속 관계)

이중 단언(Double Assertion)

정말로 강제 변환이 필요할 때 unknown을 거치면 가능합니다.

TYPESCRIPT
// ⚠️ 이중 단언 — 권장하지 않지만 가끔 필요
const value = 'hello' as unknown as number;

// 실전 예시: 테스트에서 mock 객체 만들 때
interface ComplexService {
  fetchData(): Promise<string[]>;
  processData(data: string[]): void;
  cleanup(): void;
}

// 모든 메서드를 구현하기 귀찮을 때 (테스트에서만!)
const mockService = {
  fetchData: jest.fn(),
} as unknown as ComplexService;

이중 단언은 타입 안전성을 완전히 포기하는 것이므로, 테스트 코드 에서만 사용하는 것을 권장합니다.

Non-null Assertion (!)

값이 null이나 undefined가 아님을 단언합니다.

TYPESCRIPT
// element는 HTMLElement | null
const element = document.getElementById('app');

// ❌ null일 수 있으므로 에러
// element.textContent = 'hello'; // Error

// ✅ non-null assertion — "null이 아님을 보장한다"
element!.textContent = 'hello'; // OK

// ⚠️ 하지만 런타임에 null이면 에러 발생!

! 보다 안전한 대안

TYPESCRIPT
// 방법 1: if 체크
const element = document.getElementById('app');
if (element) {
  element.textContent = 'hello'; // OK — null이 제거됨
}

// 방법 2: 옵셔널 체이닝
element?.textContent; // null이면 undefined 반환

// 방법 3: nullish coalescing과 조합
const text = element?.textContent ?? '기본값';

면접 포인트: "non-null assertion은 언제 쓰나요?"라고 물어보면, "TypeScript가 null 가능성을 감지하지만 개발자가 확실히 null이 아님을 알 때 사용합니다. 하지만 가능하면 타입 좁히기로 대체하는 것이 안전합니다"라고 답하면 됩니다.

const assertion (as const)

as const는 타입 단언과 이름이 비슷하지만, 동작은 다릅니다.

TYPESCRIPT
// as const — 값을 읽기 전용 리터럴로 좁히기
const config = {
  method: 'GET' as const,  // 'GET' 리터럴 타입
  retries: 3 as const,     // 3 리터럴 타입
};

// 객체 전체에 적용
const fullConfig = {
  method: 'GET',
  retries: 3,
} as const;
// { readonly method: 'GET'; readonly retries: 3 }

as const는 별도의 편에서 자세히 다룹니다.

타입 단언 vs 타입 선언

TYPESCRIPT
interface User {
  name: string;
  age: number;
}

// 타입 선언 — 초과 속성 검사가 동작
// const user: User = { name: '홍길동', age: 25, email: 'test' }; // ❌ Error

// 타입 단언 — 초과 속성 검사를 우회
const user = { name: '홍길동', age: 25, email: 'test' } as User; // OK ⚠️

// 타입 단언 — 필수 속성이 빠져도 에러 안 남
const partial = {} as User; // OK ⚠️ — name, age가 없는데 에러 없음

공부하다 보니 타입 단언이 초과 속성 검사를 우회 한다는 점을 놓치는 경우가 많더라고요. 가능하면 타입 선언(:)을 쓰는 것이 더 안전합니다.

satisfies 연산자 (TS 4.9+)

satisfies는 타입을 검증하면서도 추론을 유지하는 연산자입니다.

TYPESCRIPT
type ColorMap = Record<string, string | number[]>;

// as — 타입을 강제로 바꿈 (추론 정보 손실)
const colors1 = {
  red: '#ff0000',
  green: [0, 255, 0],
} as ColorMap;
// colors1.red: string | number[] — 어떤 것인지 모름

// satisfies — 타입을 검증하되 추론은 유지
const colors2 = {
  red: '#ff0000',
  green: [0, 255, 0],
} satisfies ColorMap;
// colors2.red: string — 구체적인 추론 유지
// colors2.green: number[] — 구체적인 추론 유지

satisfies는 별도의 편에서 자세히 다룹니다.

실전에서의 사용 가이드

TYPESCRIPT
// ✅ 적절한 사용
// 1. DOM 요소 타입 좁히기
const canvas = document.getElementById('canvas') as HTMLCanvasElement;

// 2. API 응답 타입 지정 (타입 가드와 함께)
const response = await fetch('/api/user');
const data = (await response.json()) as User;

// ❌ 피해야 할 사용
// 1. 타입 에러를 무시하기 위한 단언
const wrong = someValue as any; // 근본적인 타입 문제를 숨김

// 2. 빈 객체를 특정 타입으로 단언
const empty = {} as ComplexType; // 런타임에 속성 접근 시 에러

정리

  • as는 개발자가 TypeScript보다 타입을 더 잘 알 때 사용한다
  • 이중 단언(as unknown as T)은 테스트에서만 허용하자
  • !(non-null assertion)보다 타입 좁히기가 더 안전하다
  • 타입 단언은 초과 속성 검사를 우회하므로, 가능하면 : Type을 사용하자
  • satisfies는 검증과 추론을 동시에 할 수 있는 현대적 대안이다
댓글 로딩 중...