import React, { ComponentType, ComponentProps, useEffect } from "react"; import { useRouter } from "next/router"; // 제네릭 <P extends object>를 사용해, P가 컴포넌트의 props 타입임을 명확히 함 export const withAuth = <P extends object>(Component: ComponentType<P>) => { const WithAuth = (props: ComponentProps<typeof Component>) => { const router = useRouter(); useEffect(() => { const token = localStorage.getItem("accessToken"); if (!token) { router.push("/main"); } }, [router]); return <Component {...props} />; }; WithAuth.displayName = `WithAuth(${ Component.displayName || Component.name || "Component" })`; return WithAuth; }; // UserPage는 정확한 props 타입을 가지고 있음 type UserPageProps = { userName: string; age: number; }; function UserPage({ userName, age }: UserPageProps) { return ( <div> <h1>{userName}님의 페이지</h1> <p>나이: {age}</p> </div> ); } const ProtectedUserPage = withAuth(UserPage); export default function Page() { // 여기서 만약 잘못된 타입의 props를 넘기면 타입스크립트가 잡아줌. // 예를 들어: // return <ProtectedUserPage userName="홍길동" age="스무살" />; // 이 줄은 에러 발생: // Type 'string' is not assignable to type 'number'. return <ProtectedUserPage userName="홍길동" age={0} />; }
withAuth 가 고차함수임
ComponentType<P> ⇒ P 타입의 props가있는 component라는뜻이고,
ComponentProps<typeof Component> ⇒ 제네릭에 있는타입의 컴포넌트에서 props만 추출

