HTML 타입
HTMLElement 타입
HTML<태그이름>Element
라는 이름으로 DOM 노드에 대한 타입을 사용할 수 있음
const usernameInput = document.getElementById('username') as HTMLInputElement;
const submitButton = document.getElementById('submit') as HTMLButtonElement;
이벤트 타입
- 기본적으로는
Event
라는 타입을 쓸 수 있음
- 구체적으로는
-Event
로 끝나는 타입을 활용하면 됨
- 예를 들어서
oninput
이벤트에 대한 타입은 InputEvent
이고, onclick
이벤트에 대한 타입은 MouseEvent
임
submitButton.addEventListener('click', handleClick);
function handleClick(e: MouseEvent) {
e.preventDefault();
const message = `${usernameInput.value}님 반갑습니다!`;
alert(message);
}
React 타입
Props
- 인터페이스를 사용해서 타입을 지정해 줌
children
의 경우 ReactNode
라는 타입을 사용함
import { MouseEvent, ReactNode } from 'react';
import styles from './Button.module.css';
interface Props {
className?: string;
id?: string;
children?: ReactNode;
onClick: (e: MouseEvent<HTMLButtonElement>) => void;
}
const Button = ({ className = '', id, children, onClick }: Props) => {
const classNames = `${styles.button} ${className}`;
return (
<button className={classNames} id={id} onClick={onClick}>
{children}
</button>
);
}
export default Button;
- HTML 기본 Props를 타입으로 정의하고 싶다면
태그이름HTMLAttributes<노드타입>
형태의 타입을 상속해서 활용할 수 있음
- 예를 들어서 인풋 노드의 Props를 사용하고 싶다면
InputHTMLAttributes<HTMLInputElement>
와 같이 씀
import { InputHTMLAttributes } from 'react';
import styles from './Input.module.css';
interface Props extends InputHTMLAttributes<HTMLInputElement> {
}
export default function Input({ className = '', ...rest }: Props) {
const classNames = `${styles.input} ${className}`;
return <input className={classNames} {...rest} />;
}
Hook
- useState()의 경우 초깃값만 잘 지정하면 타입이 잘 추론됨
- 기본값에서 타입이 추론되지 않으면 제네릭으로 타입을 지정해줌
- 특히 빈 배열을 사용할 때 주의할 것
const names = useState<string[]>([]);
useRef()
의 경우 대상이 되는 DOM 노드의 타입을 제네릭으로 지정하고, 초깃값으로 null
을 지정해 주면, ref
Props로 내려줄 때 타입 오류가 나지 않음
const formRef = useRef<HTMLFormElement>(null);
이벤트 핸들러
- HTML 이벤트 타입과 마찬가지로
ChangeEvent
, MouseEvent
같이 -Event
로 끝나는 타입을 사용함
- 제네릭으로 DOM 노드 타입을 지정해 주면 이벤트 타겟의 타입을 지정할 수 있음
- 이때 주의할 점은 순수 HTML 자바스크립트에서 사용하는
MouseEvent
가 아니라 react
패키지에서 불러와서 사용하는 MouseEvent
타입이라는 점으로 이름이 같은 이벤트들이 종종 있으니 주의할 것
- 어떤 이벤트인지 타입을 구체적으로 지정할 필요가 없는 경우라면
SyntheticEvent
라는 타입을 사용하면 됨
import { ChangeEvent, MouseEvent, useEffect, useRef, useState } from 'react';
function handleChange(e: ChangeEvent<HTMLInputElement>) {
const { name, value } = e.target;
const nextValues = {
...values,
[name]: value,
};
setValues(nextValues);
}
function handleClick(e: MouseEvent<HTMLButtonElement>) {
e.preventDefault();
const message = `${values.username}님 환영합니다`;
alert(message);
}
Context
- 컨텍스트의 경우 컨텍스트 값의 타입을 제네릭으로 잘 지정해주면 ehla
- 이때 초깃값도 올바로 지정할 것
type Locale = 'ko' | 'en';
interface LocaleContextValue {
locale: Locale;
setLocale: (value: Locale) => void;
}
const LocaleContext = createContext<LocaleContextValue>({
locale: 'ko',
setLocale: () => {},
});