[TypeScript] 공부한 타입 정리

현용찬·2024년 9월 4일

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>) {
  // function handleClick(e: SyntheticEvent)처럼 쓸 수도 있음
    e.preventDefault();

    const message = `${values.username}님 환영합니다`;
    alert(message);
  }

Context

컨텍스트의 경우 컨텍스트 값의 타입을 제네릭으로 잘 지정해주면 된다. 이때 초깃값도 올바로 지정해야한다.

type Locale = 'ko' | 'en';
interface LocaleContextValue {
  locale: Locale;
  setLocale: (value: Locale) => void;
}

const LocaleContext = createContext<LocaleContextValue>({
  locale: 'ko',
  setLocale: () => {},
});
profile
항상 웃어 봅시다

0개의 댓글