Unknown타입은 TypeScript 3.0에 새로 출시된 타입입니다. unknown은 any와 유사하지만, 보다 타입 안전성이 보장되는 더 엄격한 타입입니다.
즉, 모든 타입은 unknown에 할당할 수 있지만, 반대로 unknown을 다른 타입에 할당하려면 반드시 타입 검사를 거쳐야 합니다.
let value: unknown;
value = "Hello"; // ✅ 모든 타입 할당 가능
value = 42; // ✅ 숫자 할당 가능
value = true; // ✅ 불리언 할당 가능
let str: string = value; // ❌ 오류 발생 (타입 검사 필요)
이제 대부분의 프론트엔드 개발자들이 TypeScript를 사용하게 되었고, 그에 따라 라이브러리들도 대부분 TypeScript를 지원하는 상황입니다. 개인적으론 불가피한 경우를 제외하면 타입 안전성과 예측 가능한 코드를 작성하기 위해선 unknown 타입 사용을 지향하는게 좋다고 생각합니다.
Unknown 타입의 변수를 다른 타입에 직접 할당하려고 하면 오류가 발생합니다.
이 문제를 해결하기 위해선 아래의 방식을 사용하여 할당하여야 합니다.
타입 단언(Type Assertion)
let unknownValue: unknown = "TypeScript";
let stringValue: string = unknownValue as string;
console.log(stringValue.toUpperCase()); // "TYPESCRIPT"
TypeScript에서는 시스템이 추론 및 분석한 타입 내용을 우리가 원하는 대로 얼마든지 바꿀 수 있습니다. 이때 "타입 단언(type assertion)"이라 불리는 메커니즘이 사용됩니다. TypeScript의 타입 단언은 개발자가 해당 값의 타입을 확신할 때는 "as" 키워드를 사용하여 타입을 단언할 수도 있습니다.
하지만 type assertion을 사용한다는 것은 개발자가 선언한 타입에 의존하기때문에 any를 사용할 때와 같이 타입 안정성을 보장하는 unknown의 장점을 무력화할 수 있습니다.
let value: unknown = 42; // 숫자를 저장
let str: string = value as string; // 🚨 잘못된 단언이지만 컴파일러가 허용함
console.log(str.toUpperCase()); // ❌ 런타임 오류 발생
타입 좁히기(Type Narrowing): 안전한 방식으로 타입 확인하기 🛡️
function processValue(value: unknown) {
if (typeof value === "string") {
console.log(value.toUpperCase()); // ✅ 안전하게 사용 가능
}
}
processValue("hello"); // "HELLO"
processValue(42); // 아무 일도 안 일어남
TypeScript에선 Narrowing은 특정 타입으로 제한하는 작업을 의미합니다. 이를 통해 코드 내에서 더 안전한 작업이 가능해지고, 오류를 줄일 수 있습니다.
따라서 unknown 타입을 사용할 땐 타입 선언보다 타입 좁히기를 추천드립니다.
참고자료
TypeScript Documentation
typescript-deep-dive
hwisaac: Typescript-narrowing
f-lab: typescript-any-never-unknown
inpa dev: 타입스크립트 타입 선언 & 종류 💯 총정리