프로그래밍프론트엔드 개발자

상수 객체의 as const 프로퍼티 타입은 어떻게 작동합니까? 이러한 객체에 대한 잘못된 타입화로 인해 발생하는 이점과 문제점은 무엇입니까?

Hintsage AI 어시스턴트로 면접 통과

답변

as const는 TypeScript에서 객체/배열의 값과 속성을 readonly 및 리터럴 타입으로 변환합니다. 이는 엄격한 타입 지정을 제공합니다: 값은 기본 타입으로 "확장"되지 않고 구체적인 값을 유지합니다.

예시:

const a = { status: 'success' }; // 타입: { status: string } const b = { status: 'success' } as const; // 타입: { readonly status: "success" }

이점:

  • 엄격한 타입 지정 (예: 문자열에 대한 switch/case, 상수 목록)
  • enums, Redux의 actionTypes, 역할 목록 등에 이상적입니다.
  • 값의 우발적 변경 방지

단점/특징:

  • 속성이 readonly가 되어 수정하려고 하면 오류가 발생합니다.
  • 부주의한 사용은 타입 불일치로 이어질 수 있습니다 (예: 문자열이 필요할 때 리터럴을 전달하는 경우).

함정 질문

질문: 문자열의 배열에 as const를 사용하면 타입은 어떻게 되며, 일반 string[]로 전달할 수 있습니까?

답변: 타입은 readonly ["a", "b", "c"]가 되며, 즉 readonly 제한이 있는 리터럴 타입의 튜플입니다. 이러한 배열은 string[] 타입과 호환되지 않으며, 수정 가능한 문자열 배열을 기대하는 곳에 직접 전달할 수 없습니다.

const arr = ['a', 'b', 'c'] as const; // readonly ["a", "b", "c"] function acceptsStrings(x: string[]) {} acceptsStrings(arr); // 오류! 타입이 호환되지 않음

주제의 미숙지로 인한 실제 오류 사례


이야기

프로젝트: actionTypes를 as const로 상수 배열로 유지했으며, 이후 string[]를 기대하는 함수에 전달하려고 했습니다. 타입 오류가 발생하여 .slice() 또는 [...arr]를 통해 명시적으로 변환해야 했습니다.


이야기

프로젝트: Redux 미니 프레임워크에서 action.type의 타입을 as const를 통해 리터럴로 정의했습니다. switch-case를 구현할 때 엄격한 타입 지정을 잊어버려 모든 리터럴을 처리하지 않아 exhaustive check가 작동하지 않았습니다 — 새로운 액션을 추가할 때까지 오류가 나타나지 않았습니다.


이야기

프로젝트: API 엔드포인트를 자동 생성할 때 키를 as const 배열로 설명했습니다. 이러한 키를 일반 Record<string, ...>의 인덱스로 사용하려고 하면 타입 불일치로 인해 실패했습니다 — 변환을 추가하거나 배열의 키 유형을 명시적으로 사용해야 했습니다.