
타입스크립트와 리액트를 주로 활용하여 프론트엔드 개발을 하다보면 종종 마주치는 type Error가 있습니다. 바로 unknown 타입으로 판단되므로, 값을 제대로 할당하라는 TS 오류를 심심치 않게 볼 수 있습니다.
any vs unknownany 타입은 타입스크립트에서 모든 타입을 할당받을 수 있는 타입으로 왠만하면 사용을 지양해야 하는 타입입니다. unknown 타입도 any 타입과 마찬가지로 모든 타입의 값이 할당될 수 있습니다.
let query : unknown
query = true;
query = 1;
query = 'string';
query = {};
query = [];
query =
이렇게만 보면 unknown 타입으로 선언된 변수가 다른 타입으로 지정된 변수에 할당할 수 있는 것처럼 볼 수 있지만, 사실 any를 제외한 다른 타입으로 선언된 변수에는 unknown 타입으로 지정된 변수를 할당할 수 없습니다.
let query : unknwon
let anyQuery: any = query // okay:)
let booleanQuery : boolean = query // Error :(
let numberQuery : number = query // Error :(
let stringQuery : string = query // Error :(
let objectQuery : object = query // Error :(
또, unknown 타입으로 선언된 변수는 프로퍼티에 접근이 불가능하고, 메서드를 호출할 수 없으며, 인스턴스도 생성할 수 없습니다.
let query: unknown
// 객체
query.foo.bar // Error :(
// 배열
query[1] // Error :(
// 메서드
query.actSomething() // Error :(
// 함수
query() // Error :(
// 인스턴스 생성
new Query() // Error :(
any가 사용될 곳이라면, unknown 타입으로 대체가 가능합니다. 단, 앞에서 다룬 예시처럼 unknown 타입으로 지정된 변수를 any를 제외한 다른 타입을 지정된 변수에 할당하는 것만 주의하면 됩니다.
Type Guard
특정 객체의 프로퍼티들로 타입을 판단하는 util function에 unknown Type을 사용할 수 있습니다.
const isType = <T> (
queryToBeChecked : unknown,
propertyToCheckAs : keyof T
): queryToBeChecked is T =>
(queryToBeChecked as T)[propertyToCheckAs] !== undefined
queryToBeChecked에 어떤 타입의 값이 들어와도 상관없을 때, any 타입으로 선언해도 되지만, 이 때 unknown타입을 활용한 Type Guard 를 활용해 어떤 타입의 값이 전달되는 지 확인할 수 있다.
이렇게 unknown을 어떻게 활용할 수 있는지 알아보았습니다. any 타입을 지양하기 위해 tsconfig.json에 strict:true 옵션을 준 것과 더불어, unknown 타입을 응용해서 활용하면 좋을 것 같습니다.