TypeScript에서 이전 코드에 선언해 두었던 타입을 변경하기 위해 as
를 사용할 수 있다. 타입을 검사하여 오류를 잡아내는 것이 TypeScript를 사용하는 이유인만큼 코드 중간에 타입을 변경하는 것이 안전하다고 하기는 어렵지만, 그래도 기능을 구현하다보면 타입을 변경해야 하는 경우가 있을 수 있다.
명확하게 다른 타입으로 변경하기 위해서는 unknown
으로 변경 후 변경하고자 하는 타입으로 변경할 수 있다. 그러나 서로 관계가 있는 타입으로 변경하기 위해서는 unknown
을 생략할 수 있다.
const num: number = 0;
...
// number 와 string은 관계가 없는 명확히 다른 타입이기 때문에 unknown을 생략할 수 없다.
(num as string).substr(0, 5); // error! (의도적으로 바꾼 것이라면 unknown을 추가하라는 오류가 뜬다.)
(num as unknown as string).substr(0, 5); // okay
const div = document.createElement('div');
...
// HTMLElement와 HTMLDivElement는 서로 부모-자식 관계이기 때문에 unknown을 생략할 수 있다.
(div as HTMLElement).textContent; // okay
(div as unknown as HTMLElement).textContent; // okay
이전 글에서 any
를 사용하지 않고 타입을 지정할 수 있는 몇 가지 방법에 대해 포스팅을 했었다. 그 중 하나가 React.ChangeEvent
에 관련한 것이었다.
e: React.ChangeEvent<HTMLInputElement>
를 사용하면 input 태그 안에 있는 value
값을 바로 접근할 수 있기 때문에 onChange
이벤트를 비교적 쉽게 사용할 수 있다. 다만, onClick
이벤트라면 얘기가 달라질 수 있다. 아래 코드에 예시가 있다.
import React from 'react';
const App = () => {
const thisText = 'text';
const getDivText = (e: React.MouseEvent<HTMLDivElement>) => {
return e.target.textContent; // 오류: 'EventTarget' 형식에 'textContent' 속성이 없습니다.
}
const getInputText = (e: React.ChangeEvent<HTMLInputElement>) => {
return e.target.value; // okay
}
return (
<>
<div onClick={getDivText}>{thisText}</div>
<input onChange={getInputText} value={thisText}></input>
</>
);
}
위 예시에서 onChange
를 사용하여 ChangeEvent
의 target
을 사용하면 value
, textContent
등 여러가지 속성들을 사용할 수 있지만, MouseEvent
의 target
에 존재하는 속성이라고는 addEventListener
, dispatchEvent
, removeEventListener
밖에 없다.
그렇다고 TypeScript에서 MouseEvent
의 target
의 textContent
등의 속성들을 사용할 수 없는 것은 아니다. 이 때 필요한 것이 바로 형변환이다. 아래에 위 코드를 수정한 예시가 있다.
import React from 'react';
const App = () => {
const thisText = 'text';
const getDivText = (e: React.MouseEvent<HTMLDivElement>) => {
return e.target.textContent; // 기존 코드: 오류
return (e.target as HTMLElement).textContent; // 수정 코드: okay
}
return (
<div onClick={getDivText}>{thisText}</div>
);
}
HTMLElement
에는 textContent
뿐만 아니라 className
, id
등의 속성들이 모두 포함되어 있다. 기존에는 이벤트가 MouseEvent
로 정의되어 있어서 그 target
의 속성을 제한적으로만 사용할 수 있었는데, 수정된 코드에서는 이벤트의 target
자체의 타입을 HTMLElement
로 형변환 함으로써 다른 속성들을 사용할 수 있도록 만들어주는 것이다.
이러한 형변환은 기존에 선언한 타입을 변경하는 것이기 때문에, 특히 협업을 할 때에는 (대부분의 프로젝트가 협업으로 진행되겠지만..!) 주의해서 사용할 필요가 있다. 기존 타입을 선언했을 때의 의도와 전혀 다르게 사용될 가능성이 있기 때문이다.
TypeScript never, any, 타입 캐스팅
TypeScript type assertions 공식 문서