[Next.js, TypeScript] Custom Type을 한 곳에서 관리하기

Yeong·2024년 12월 31일

각각의 component와 pages마다 type을 선언할 때 마다, type이나 interface를 재선언해주는 것이 효율적이지않은 것 같다고 느낀 찰나에, 다른 한 파일에 타입을 지정해놓고 필요할때 마다 꺼내서 사용하면 좋을 것 같았다.
살펴보니 NextJS 프레임 워크에서 구현이 되어 있었는데 next-env.d.ts 가 있었고,
nextjs 프로젝트를 생성 했을때, 위의 파일이 자동적으로 생성된다.

🌳 next-env.d.ts 🌳

  • nextjs 공식문서에서도 타입과 인터페이스를 관리하는 파일로 해석한다.
  • 해당 파일에 타입을 지정 했을 시, 자동으로 import없이 타입들을 사용 가능하다는 것이 큰 장점이다.
  • api url같은 상수 값도 여기에 type지정이 가능하다.
// next-env.d.ts

/// <reference types="next" />
/// <reference types="next/image-types/global" />

// 예시: 전역적으로 사용될 사용자 정의 타입
interface CustomType {
   id: string;
   name: string;
}

type PropsCustomButton = {
   title:string;
   handleClick?: MouseEventHandler<HTMLButtonElement>;
   btnType?: "button" | "submit";
   textStyles?: string;
   rightIcon?: string;
   isDisabled?: boolean;
   className?: string;
}


// 예시: 프로젝트 전체에서 사용될 상수
declare const API_BASE_URL: string;

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.

이런식으로, CustomButton 컴포넌트가 필수로 받는 props 선택적으로 받을 수 있는 props의 타입을 모두 정의하면된다.

  • 필수로 받는 props : 컴포넌트가 동작하기 위해 반드시 필요한 값들을 필수(props)로 지정한다. 예를 들어 title은 버튼에 표시할 텍스트이므로 필수로 설정해야한다.
  • 선택적으로 받을 props : 특정 조건에서만 사용할 필요가 있는 값들을 선택적(props)으로 지정한다. 예를 들어 handleClick이나 isDisabled는 사용자가 이 값을 전달하지 않으면 기본값을 사용할 수 있도록 설정한다.
type PropsCustomButton = {
  // 필수 props
  title: string; // 버튼에 표시할 텍스트, 필수
  btnType?: "button" | "submit"; // 버튼 타입, 기본값이 "button"
  
  // 선택적 props
  handleClick?: MouseEventHandler<HTMLButtonElement>; // 클릭 이벤트 핸들러, 선택적
  textStyles?: string; // 텍스트 스타일, 선택적
  rightIcon?: string; // 아이콘, 선택적
  isDisabled?: boolean; // 버튼 비활성화 여부, 선택적
  className?: string; // 추가적인 클래스명, 선택적
}

🌳선택적 props (?):🌳
타입 정의에서 선택적으로 받을 수 있는 값을 나타내는 타입스크립트 기법.
타입스크립트에서 props를 정의할 때, 선택적 값은 ?를 사용하여 정의된다.


type Props = {
  title: string; // 필수
  handleClick?: () => void; // 선택적
};

여기서 handleClick?: () => void;와 같이 정의된 handleClick은 선택적이다.
즉, 해당 prop을 전달하지 않아도 된다.


참고로! 무조건 선언해줘야 하는 부분이 있다.

tsconfig.json에 반드시 include해줘야하는데 해당 파일 내부 속 include 배열 안에 "next-env.d.ts"를 반드시 추가해줘야 한다.
이 구분은 기본적으로 빌드시에 자동생성되어 있지만 없다면 추가해주자!

 "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    ".next/types/**/*.ts"
  ],

25.01.23 업데이트 !!

작업 중 "next-env.d.ts"에 선언해놓은 타입들이 깃에 반영되지않고, 내용들이 사라져서 살펴보니 우선 .gitignore에 포함되어있었고 그렇다면 왜 기본으로 .gitignore에 들어가있을까를 생각해보며 내용을 좀 더 살펴봤다.

Custom Type Declarations

공식문서 왈 :
커스텀 타입을 선언해야 할 때, next-env.d.ts를 수정하고 싶을 수 있습니다. 그러나 이 파일은 자동으로 생성되므로 변경 사항이 덮어쓰여질 것입니다. 대신 새 파일을 생성하고 new-types.d.ts라고 이름을 짓고 이를 tsconfig.json에 참조하세요:

{
  "compilerOptions": {
    "skipLibCheck": true
    //...생략...
  },
  "include": [
    "new-types.d.ts",
    "next-env.d.ts",
    ".next/types/**/*.ts",
    "**/*.ts",
    "**/*.tsx"
  ],
  "exclude": ["node_modules"]
}

next-env.d.ts 파일이 있는 위치와 동일한 위치에 new-types.d.ts 파일을 생성하고, 해당 파일 내에 타입을 선언해주면된다!

//new-types.d.ts
type PropsCustomButton = {
  title: string;
  handleClick?: MouseEventHandler<HTMLButtonElement>;
  btnType?: "button" | "submit";
  textStyles?: string;
  rightIcon?: string;
  isDisabled?: boolean;
  className?: string;
};

export default PropsCustomButton; //반드시 export를 해주어야함.

그리고 CustomButton.tsx에서 사용하기.

"use client";

import PropsCustomButton from "../../../new-types"; //이와 같이 import 시킨다.

import Image from "next/image";
import "./CustomButton.scss";

const CustomButton = ({
  title,
  handleClick,
  btnType = "button",
  textStyles,
  rightIcon,
  isDisabled = false,
  className = "",
}: PropsCustomButton) => {
  return (
    <button
      className={`listBtn ${className}`} // className은 추가될 수 있도록 설정
      type={btnType}
      disabled={isDisabled}
      onClick={handleClick}>
      <span className={`flex-1 ${textStyles}`}>{title}</span>

      {rightIcon && (
        <div>
          <Image src={rightIcon} alt="icon" fill className="object-contain" />
        </div>
      )}
    </button>
  );
};

export default CustomButton;

그리고 실제 위 버튼 공통 컴포넌트를 사용할 때에

<CustomButton btnType="button" title="타이틀영역" className="buttonCommon" />

이런식으로 타입에 맞게 작성해주면 되는데, 예를들어 title에서 string이 아닌 number를 작성하면 오류가 난다.!!

💭 next-env.d.ts

  • Next.js 프로젝트에서 TypeScript를 사용할 때 자동으로 생성되는 파일
  • TypeScript 컴파일러에게 Next.js 프로젝트의 환경을 이해하고 알려주는 역할을 한다.

next-env.d.ts 파일이 Typescript 컴파일러로 인해 자동으로 생성되는 시점

  1. 프로젝트 초기화 시
  2. TypeScript 컴파일 시
  3. 외부 라이브러리의 타입이나 커스텀 타입 사용 시

next-env.d.ts 파일이 하는 일

  • 타입 선언
    프로젝트에서 사용하는 외부 라이브러리나 모듈의 타입을 선언함으로써 TypeScript가 해당 모듈의 타입을 인식하고 사용할 수 있다.

  • 환경 설정
    환경 변수의 타입 선언이나 모듈의 경로 설정 등을 포함한 Next.js 프로젝트의 환경 설정과 관련된 TypeScript 타입을 정의할 수 있다.

  • 커스텀 타입
    프로젝트 내에서 공유되는 커스텀 타입을 정의할 수 있다. 프로젝트 전체에서 일관된 타입을 유지하고 재사용하기 용이해진다.

참고

공식문서 https://nextjs-ko.org/docs/pages/building-your-application/configuring/typescript

0개의 댓글