Closed limejin closed 6 days ago
children 타입은 ReactNode 또는 undefined 타입으로 정의가 되어있습니다. ReactNode 타입은 ReactElemnt 외 boolean, string 등 여러 타입을 포함하고 있는 타입으로 비교적 넓은 타입을 가집니다. 타입을 좁히기 위해서는 아래 코드와 같이 제네릭을 사용할 수 있습니다.
type MyComponentProps<T> = PropsWithChildren<{
children?: T | T[]; // T 타입의 자식 요소만 허용
}>;
children에 사용된 ReactNode는 string, ReactElement 등 여러 타입을 포함하고 있는 타입입니다. 따라서 특정 조건의 타입으로 타입을 좁히고 싶다면 아래와 같이 정의할 수 있습니다.
type PropsWithChildren<P> = P & { children?: React.ReactElement };
PropsWithChildren
에서 children의 타입으로 허용하는 ReactNode
는 아래와 같은 타입 정의를 따릅니다.
// @types/react
type ReactText = string | number
type ReactChild = ReactElement | ReactText // ReactElement에는 string, number가 허용되지 않음
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined
이처럼 ReactNode
는 ReactElement
외에도 boolean, number 등 여러 타입을 포함하고 있습니다.
따라서 PropsWithChildren
의 children 타입을 제한하여 정의하는 방법으로 허용하는 타입을 좁힐 수 있습니다.
type PropsWithChildren<P> = P & {
children?: ReactElement | undefined
}
위와 같이 PropsWithChildren 타입을 재정의했다면, 아래처럼 children에 들어갈 수 있는 타입이 제한됩니다.
interface ComponentProps {
className?: string
}
const Component = ({ children }: PropsWithChildren<ComponentProps>) => {
return <div>{children}</div>
}
<Component><div>Hello</div></Component> // ✅ ReactElement에는 jsx 타입이 허용됨
<Component>text</Component> // ❌ ReactElement에는 string 타입이 허용되지 않음
<Component>{123}</Component> // ❌ ReactElement에는 number 타입이 허용되지 않음
📚 252p 📌 현재 코드에서 children 타입이 넓은 이유를 설명하고 타입 범위를 좁혀주세요. (좁히는 데 특정한 조건은 없습니다. 현재보다 좁아지면 됩니다.)
type PropsWithChildren<P> = P & { children?: ReactNode | undefined };