TypeScript
의 unKnown
과 any
를 들어 보신 적 있으신가요? 이 두 가지 타입이 JavaScript
대신 TypeScript
를 쓰는 이유중 상당 부분을 차지하고 있다고 생각합니다.
TypeScript의 등장 배경에는 JavaScript의 유연함이 오히려 개발 단계에서 발생하는 에러들을 잡지 못하는데에 있었습니다.
Type을 선언하지 않다보니 논리적으로 말이 되지 않는 코드들도 정상적으로 동작하게 보이게 되는 것이죠
예를 들어 아래의 코드처럼 number
의 값과 string
의 값을 더하게 되면 check123
이라는 string
값을 나타나게 됩니다. type
체크를 따로 하지 않으니 string
값과 더하는 number type
인123
을 string
으로 캐스팅해서 더한 결과 값을 도출한거죠
의도한 결과라면 상관 없지만 의도하지 않았을 경우 치명적인 오류를 내뱉을지도 모릅니다.
이것처럼 기본적으로 javascript
는 모든 type에 대해 처리가 가능한 any
타입을 기반으로 만들어졌습니다.
const typeNumber = 123;
const typeString = 'Check'
const typeCheck = typeString + typeNumber;
console.log(typeCheck)
check123
아래 글처럼 type
에 대한 선언을 해주게 되면 타입이 체킹되어 string + number
의 합은 오류를 표출하도록 바꿔서 미리 코드 단계에서 error을 잡도록 도와줍니다.
의도한 대로 number
type의 결과 값만 나오게 한것이죠. 이는 javaScript
의 오류를 빠르게 잡을 수 있도록 했고 typeScript
로 대다수의 프로그래머들이 넘어가는 역할을 하게 됩니다.
const typeNumber:number = 123;
const typeString:string = 'Check'
const typeCheck:number = typeString + typeNumber;
typeCheking error
위에서 설명했다싶이 기본적으로 any
타입은 코딩을 함으로써 많은 유연함을 주지만 단점도 명확했습니다. 타입을 체킹하기 위해 쓰는 typeScript
를 any
선언으로 쓰게 되면 그 의미가 없게되는 것이죠.
하지만 개발을 하면 모든 타입을 알 수 없는 경우도 있기 마련입니다.
기본적으로 모든 type
선언해서 쓰지만 외부 api나 다른 프로그램에서 모든 type
을 다 알 수 없는 경우도 있기에 any
타입을 썼던 것이죠.
그래서 나온 게 unknown
타입입니다. unknown
type은 typeScript
의 3.0.0 version
에서부터 나온 타입으로 any
type처럼 모든 타입을 할당해서 사용 할 수 있습니다.
let check : unknown;
check = true // OK (boolean)
check = 123 // OK (number)
check = 'check' // OK (string)
check = {} // OK (object)
export const isEmptyCheck = (value: unknown): boolean => {
if (value === null || value === undefined || value === '') {
return true;
}
if (value instanceof Date) {
return isNaN(value.getTime());
}
if (typeof value === 'string') {
return value.trim() === '';
}
if (Array.isArray(value)) {
return value.length === 0 || value.every(isEmptyCheck);
}
if (typeof value === 'object' && value !== null) {
return Object.values(value).every(isEmptyCheck);
}
return false;
};
간단하게 만든 null 체크 로직입니다.
다양한 type의 값을 받아야 하니 간단하게 설정할때는 any
로 받아서 처리를 하면 되겠죠?
하지만 이처럼 타입을 받아서 체킹하는 것이 typeScript
를 올바르게 사용한다고 할 수 있습니다.
저렇게 typeGuard
형식처럼 각각의 typeof
를 통해 따로따로 그에 따른 대응을 처리할 수 있게 하는 것이죠.
TypeGuard
란?
특정 범위 내에서 변수의 타입을 보다 구체적으로 좁혀나갈 수 있게 하는 기능입니다. 이를 통해 타입을 보다 정확히 추론할 수 있으며, 개발자는 타입 관련 오류를 미리 방지하고, 더 안전하게 코드를 작성할 수 있습니다. Type Guard는 크게 사용자 정의 Type Guard와 TypeScript가 제공하는 Type Guard로 나눌 수 있습니다.
저 같은 경우는 type
이 어떻게 들어올지 아는 경우는 type
을 다 선언해서 사용을 하고 어떤 타입이 올지 알 수 없는 경우에는 any
타입으로 처음에 로직을 설계하고 type
이 어떻게 들어올지 아는 경우는 unknown
타입을 통해서 각각의 타입가드로 타입의 안정성을 확보하는 방향으로 코딩하는 것을 선호합니다.
코딩 방법에는 여러가지가 있지만 본래 의미를 알고 그 의미가 코딩의 편리함을 넘어서지 않는 편에서 효율성과 안정성에 중점에 두고 코딩을 하는 것이 좋다고 생각합니다.
자신에게 맞는 방안으로 any
와 unknown
을 활용하면 어떨까요?
틀린 점이 있다면 댓글로 남겨주세요!
여러분의 코딩 스타일이나 방법들을 댓글로 남겨주시면 재밌는 이야기를 나눌 수 있을 것 같습니다.
안녕하세요, 타입스크립트를 잘 몰라서 문의드립니다.
타입스크립트로 작성한 경우, TypeGuard 기능으로 if 조건의 instanceof 문법으로 Date 타입임을 유추하여 if 블록 내에서 캐스팅없이 Date 형으로 인식하고 메소드를 사용할 수 있다는 것 맞을까요?
그리고 이 과정은 컴파일러를 통해 오류를 도출하는지도 궁금합니다!