const handleNextClick = (e: any) => {
// e: React.MouseEvent<HTMLDivElement> 와 같이 타입지정!
if(favoriteArtist === ""){
setArtistAlert(true);
setTimeout(() => {
setArtistAlert(false);
}, 2000);
setPageX(e.pageX);
setPageY(e.pageY);
} else {
history.push("/test");
}
}
리액트에서 이벤트 객체의 타입은 React 객체로로부터 꺼내 쓴다!
change 이벤트라면 ChangeEvent
, Touch 이벤트라면 TouchEvent
, Click 이벤트라면, ClickEvent
가 아니라 MouseEvent
를 사용해준다.
그리고 나서 제네릭 타입으로는 해당 함수를 이벤트로 걸어준 태그의 타입을 찾아 지정한다.
나와 같은 경우는 div 태그에 onClick
프로퍼티로 함수를 할당했으므로, HTMLDivElement
타입을 써주었다.
타입을 잘 못 설정하면 아래와 같은 오류가 발생하기도 한다.
Property 'pageX' does not exist on type 'ChangeEvent<HTMLDivElement>'.
import { RouteComponentProps } from 'react-router-dom';
function ArtistsPage({ history }: RouteComponentProps) {
const viewState = useSelector((state: RootState) => state.viewReducer);
const { view } = viewState;
const dispatch = useDispatch();
// 하단부 코드 생략
------------
// RouteComponentProps에 더해 props를 무언가 더 내려주었다면, extends를 써서 새 인터페이스를 선언하자!
interface landingPageInterface extends RouteComponentProps {
handleThemeChange: Function;
}
function LandingPage(props: landingPageInterface) {
const landingPageContainer = useRef<HTMLDivElement | null>(null);
history
를 쓰면 타입스크립트에서는 당연히 prop 타입을 지정해주어야 한다. 물론이지, react-router-dom
에서 이미 라우트 컴포넌트 프롭스라는 타입을 제공한다. 이를 임포트해와서 사용하자! 물론 위 코드처럼 객체 구조분해 하지 않고, props: RouteComponentProps
와 같이 사용해주어도 된다!
위 부분과 같은 코드인데, 사실 내가 짠 서버 API이지만, 응답 객체의 형식을 기억할 리가...^^;
그래서 콘솔로 찍어보았다!
처음에는 응답객체 전용 인터페이스나 타입이 어딘가에 미리 준비되어있을 것이라 생각했으나, 내가 못 찾은 것인지 원래 없는 것인지 모르겠으나, 결국 못 찾아서 data
에 대한 부분만 따로 만들어주었다!
type result = {
createdAt: string;
favoriteGroup: string;
girlGroupName: string;
mbti: string;
updatedAt: string;
__v: number;
_id: string;
}
interface resultResp {
data: {
results: result[]
}
}
let thisMonth: number | string = new Date().getMonth() + 1;
thisMonth = thisMonth.toString();
if(thisMonth.length === 1){
thisMonth = "0" + thisMonth;
}
이 부분은 뭔가 야무지게 처리하는 방법이 있을 것도 같은데, 처음에 number로 타입을 지정해놓았다가, string으로 바꾸는 과정이 있어서 number
, string
하나로 지정하면 오류가 나서 위와 같이 처리해주었다... 타입스크립트를 쓰다보면, 정말 왜 자바스크립트가 유연한 언어, 혹은 근본없는 언어라고 불리는지 조금은 알겠다...
const constraintsRef = useRef(null);
interface ResultAlbumCoverProps {
constraintsRef: MutableRefObject<null>;
albumCoverUrl: string;
}
props로 내려 받고 나서 constraintsRef
는 MutableRefObject<T>
로 타입지정!
interface FitMeType {
[key: string]: number;
}
let findNotFitMe = (obj: FitMeType, num: number) => {
for (let key in obj){
if (obj[key] === 5 - num){
notFitMeGroups.push(key);
}
}
if (notFitMeGroups.length === 0){
findNotFitMe(obj, num + 1);
} else {
return;
}
}
for...in 문
을 통해 key로 객체의 값들을 순회하는데, key의 타입이 지정되지 않아 에러가 발생하였다.
[key: string]: number;
와 같이 키에 타입을 지정해주니 에러가 해결되었다!
interface ResultFooterProps {
handleKakaoBtn: React.MouseEventHandler<HTMLButtonElement>;
handleTwitterBtn: React.MouseEventHandler<HTMLButtonElement>;
handleFacebookBtn: React.MouseEventHandler<HTMLButtonElement>;
handleCopyBtn: React.MouseEventHandler<HTMLButtonElement>;
}
위와 같이 React 객체를 통해 이벤트 핸들러 타입들을 꺼내 쓸 수 있다. 제네릭 타입 안에 해당 이벤트 핸들러를 할당할 태그의 타입까지 지정해준다!
interface ResultPercentProps {
labels: string[];
dataArr: number[];
setLabels: React.Dispatch<React.SetStateAction<string[]>>;
setDataArr: React.Dispatch<React.SetStateAction<number[]>>;
handleResultComponentClick: React.MouseEventHandler;
percentIndex?: number;
constraintsRef?: MutableRefObject<null>;
handleCloseBtn?: any;
}
다행이도 타입스크립트에서 useState를 사용하고 구조분해할당으로 setter 함수를 선언 할당해주고 나면!
마우스 호버로 해당함수의 타입을 살펴볼 수 있다!!