typescript react index.d.ts 파일에서 ReactNode의 type을 가져왔다.
ReactElement외에도 여러가지를 포괄하는 type이다.
클래스형 컴포넌트는 render메소드에서 ReactNode를 return한다.
type ReactFragment = Iterable<ReactNode>; // ReactNode의 이터러블 형태
interface ReactPortal extends ReactElement {
key: Key | null;
children: ReactNode;
} // Portal은 key값을 가진 ReactNode
type ReactNode =
ReactElement| string | number |
ReactFragment | ReactPortal | boolean | null | undefined;
React.createElement 함수를 사용하면 ReactElement Type이 return된다.
ReactElement는 type과 prop을 갖는데, type으로는 JSX Element나 string이 올 수 있다.
type JSXElementConstructor<P> =
| ((props: P) => ReactElement<any, any> | null)
| (new (props: P) => Component<any, any>);
interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
type: T;
props: P;
key: Key | null;
}
React에서 JSX를 사용하면, 바벨이 이를 React Element의 형태로 트랜스파일링 해준다.
트랜스파일은 컴파일과 많이 비교된다.
컴파일은 한 언어로 작성된 소스코드를 다른 언어로 변환시키는 것,
트랜스파일은 한 언어로 작성된 소스 코드를 비슷한 수준의 추상화를 가진 다른 언어로 변환하는 것이다.
그렇기때문에, JSX를 사용하는 함수형 컴포넌트에서는 ReactElement type이 return 되는 것이다.
const element = (
<h1 className="greeting">
Hello, world!
</h1>
); // 트랜스파일이전
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
); // 트랜스파일 이후
JSX.Element는 JSX라는 namespace에 정의되어 있다.
JSX.Element는 ReactElement를 제너릭으로 확장한것이다. type, prop이 any type을 갖는다.
namespace란? 인터페이스, 클래스, 함수 등을 묶는 단위로, 모듈과 비슷한 역할을 한다.
모듈이 없었을때는, 네임스페이스를 통해 모듈을 관리하고 재사용했다. 타입스크립트 공식문서에도 현재는 모듈사용을 권장한다.
declare global {
namespace JSX {
interface Element extends React.ReactElement<any, any> { }
interface ElementClass extends React.Component<any> {
render(): React.ReactNode;
}
ref)
types/react/index.d.ts(React 18.0 version 기준) - https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts
네임스페이스,모듈 : https://www.typescriptlang.org/docs/handbook/namespaces-and-modules.html