토이프로젝트를 하던 중 as 키워드에 대해서 궁금해서 정리해보려고 한다.
엄청 자세하게 파고들어가진 않고
개념과 사용법 정도를 익히기 위해 정리하고자 글을 작성했다!
역할 : Type Assertion(타입 단언)
설명: '컴파일' 단계에서 타입 검사를 할 때 타입스크립트가 감지하지 못하는 애매한 타입 요소들을 직접 명시해주는 키워드이다.
예시)
const myCanvas = document.getElementById("main_canvas");
타입스크립트는 그저 myCanvas
가 여러 HTMLElement
중 어느 하나의 HTMLElement
만을 가질 것이란 사실 밖에 알지 못한다.
하지만 아래와 같이 as
키워드를 사용하면?
const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;
myCanvas
가 HTMLCanvasElement
를 가진다는 것을 알게 되며 에러의 확률을 줄일 수 있게 된다.
또한 as 키워드(type assertion)는 오직 컴파일 단계에서만 실행되며 런타임 단계에서는 삭제된 채로 실행된다.
즉, 컴파일 단계에서 제대로 넘어갔다면 런타임 단계에서의 에러 발생은 일어나지 않는다는 말이다.
추가적으로 타입 단언에는 2가지 종류가 있는데
위의 코드를 바꿔보자면 아래와 같다.
const myCanvas = <HTMLCanvasElement>document.getElementById("main_canvas");
그렇다면 어떤걸 사용해야 할까?
// 타입 단언에는 두 가지 종류가 있다.
1: <Fish>pet
2: (pet as Fish)
이 때 1 번은 런타임과 컴파일 단계에서 모두 돌아가고
2 번은 컴파일 때만 돌아간다.
만약 리액트로 개발할 시 꺽쇠(<>)로 타입캐스팅 하는 것은 TSX 태그 문법이랑 비슷하기 때문에 as 를 추천한다.
추가적으로 as 키워드를 두 번 쓰면 기존에 A 타입이었던 것을 B 타입으로 바꿀 수도 있다.
const a = (expr as any) as T;
만약 expr의 타입이 원래 string[]였다면
number 타입인 T를 바로 대입하지 못할 것이다. 따라서 expr의 타입을 any로 먼저 바꿔준 다음, 마침내 number 타입으로 assert해줄 수 있는 것이다.
역할: Type Guard(타입 가드)
설명: typeof 같은 걸로 타입을 따져서 분기 처리 하는 역할을 TS 에선 is 이다.
예시)
if (isFish(Fish 타입 인 애)) { // isFish에서 Fish 타입이면 타입 가드에 의해서 조건문 통과
console.log(Fish 타입인 애); // OK
console.log(Bird 타입인 애); // Error
} else { // Bird 타입인 애가 들어가면 여기로!
console.log(Fish 타입); // Error
console.log(Bird 타입); // OK
}
function isString(test: any): test is string{
return typeof test === "string";
}
function example(foo: any){
if(isString(foo)){
console.log("it is a string" + foo);
console.log(foo.length); // string function
}
}
example("hello world");
위 isString()
함수를 살펴보면 return문의 값이 true일 때, test is string이란 type predicate 구문이 있기 때문에 타입스크립트는 이 함수를 호출한 범위 내에서 isString()
의 결과 타입을 string으로 좁힌다.
그러니까 isString()
함수를 거쳐서 return 값이 true라면, type predicate에 적은 말 그대로 '함수가 호출된 범위 내에선 test를 string타입으로 보라' 는 것이다.
위 as 키워드와 마찬가지로 is 키워드 역시 컴파일 단계에서만 사용되며 런타임 단계에서는 순수한 js 파일과 동일하게 동작한다.
추후에 is는 좀 더 설명을 추가해야 겠다.
정리
Type Assertion(타입 단언)으로, 컴파일 단계에서 타입스크립트가 잘못 혹은 보수적으로 타입을 추론하는 경우 개발자가 수동으로 컴파일러에게 특정 변수에 대한 타입 힌트를 주는 것이다.
Type Guard(타입 가드)로, as가 특정 변수 하나에 국한된 것이라면 is 키워드는 한정된 범위 내의 모든 변수에 대해서 일괄적으로 적용할 수 있는 키워드이다.