Post

타입스크립트 확장하기 - 리액트 요소 타입

우아한 타입스크립트 도서의 일부 내용을 정리한 포스트입니다.

리액트 요소 타입

ReactNode, ReactElement, JSXElement

React

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// JSXElement
const jsxElement = <div>Hello, World!</div>;

// ReactElement
const reactElement = React.createElement('div', null, 'Hello, World!');

// ReactNode
const reactNode = (
  <div>
    {jsxElement}
    {reactElement}
    {/* 문자열, 숫자, 배열 등도 포함될 수 있음 */}
    Additional text
  </div>
);

✅ ReactNode

1
2
3
4
5
6
7
8
9
10
11
type ReactText = string | number;
type ReactChild = ReactElement | ReactText;
type ReactFragment = {} | Iterable<ReactNode>;

type ReactNode = 
    | ReactChild
    | ReactFragment
    | ReactPortal
    | boolean
    | null
    | undefined;

ReactNode는 ReactChild, ReactFragment, ReactPortal, boolean, null, undefined의 타입을 가진다. 즉, 리액트에서 렌더링할 수 있는 모든 요소를 포함한다고 볼 수 있다.

사용예

어떤 타입이든 받을 수 있게 지정하려면 ReactNode 타입을 사용하면 된다.

1
2
3
interface ComponentProps {
    children: React.ReactNode
}

✅ ReactElement

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
interface ReactElement<P = any,
    T extends string | JSXElementConstructor<any> = 
    | string
    | JSXElementConstructor<any>
> {
    type: T;
    props: P;
    key: Key | null
}

const element = React.createElement(
    "h1",
    {className: "greeting"},
    "hello world"
)

ReactElement는 UI를 표현하는데 사용되며, createElement 메소드를 사용하여 생성한 요소이다. 리액트에서 사용하는 가상돔의 구조를 나타낸다.

사용예

1
2
3
4
5
6
7
8
9
10
11
12
13
interface IconProps {
    size:number
}

interface Props {
    icon: React.ReactElement<IconProps>
}

const Item = ({icon}:Props) => {
    const iconSize = icon.props.size;

    return <li>{icon}</li>
}

✅ JSX.Element

JSX는 자바스크립트의 확장 문법으로 리액트에서 UI를 작성하는데 사용된다.
JSX.ElementJSX 문법으로 작성된 요소를 말하며, HTML과 유사한 문법으로 작성한다. 작성된 JSX.Element는 자바스크립트로 컴파일되어 React.createElement함수로 변환된다. 이 과정을 통해 JSX.ElementReactElement로 변환되어 사용된다.

1
2
3
4
5
declare global {
    namespace JSX {
        interface Element extends React.ReactElement<any,any>{}
    }
}

사용예

1
2
3
4
5
6
7
8
9
10
11
12
13
interface Props {
    icon: React.ReactElement<IconProps>
}

const Item = ({icon}:Props) => {
    const iconSize = icon.props.size;

    return <li>{icon}</li>
}

const App = ()=>{
    return <Item icon={<Icon size={14} />} />
}
This post is licensed under CC BY 4.0 by the author.