かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

TypeScript React JSX.Element にハマる

TypeScript React の FC, VFC という型は過渡期で将来的に変更になる可能性があるからコンポーネントの返す型は JSX.Element にした方が良いという記事を読んで新しいプロジェクトでは JSX.Element を使うようにしたのですが、そこでハマったことのメモ

null を返せない

条件によって表示したくないようなコンポーネントnull を返したりしていましたが、JSX.Elementnull を含まないようです

const ComponentVFC: VFC = () => {
  return null;
};
// => OK

const ComponentJsxElement = (): JSX.Element => {
  return null;
};
// => Type 'null' is not assignable to type 'Element'.

Return type を JSX.Element | null にすれば OK

- const ComponentJsxElement = (): JSX.Element => {
+ const ComponentJsxElement = (): JSX.Element | null => {
  return null;
};
// => OK

VFC も JSX.Element も Array.map を直接返せない

リストの中身の作成だけ別関数に出してしまいたい様な場合。
VFC は大丈夫な気がしてたけど記憶違いでした。

const list = ['ichigo', 'aoi', 'ran'];

const ListVFC: VFC = () => {
  return list.map((item) => <span key={item}>{item}</span>);
};
// => Type 'Element[]' is missing the following properties from type 'ReactElement<any, any>': type, props, key

const ListJsxElement = (): JSX.Element => {
  return list.map((item) => <span key={item}>{item}</span>);
};
// => Type 'Element[]' is not assignable to type 'Element'.

JSX.Element[] はコンポーネントとして扱えないので、純粋な関数として定義して使う

🙅 コンポーネント扱いできない

const list = ['ichigo', 'aoi', 'ran'];

const ListItem = (): JSX.Element[] => {
  return list.map((item) => <span key={item}>{item}</span>);
};

const Component = (): JSX.Element => {
  return <div><ListItem /></div>;
};
// => 'ListItem' cannot be used as a JSX component.
// =>  Its return type 'Element[]' is not a valid JSX element.

🙆

const list = ['ichigo', 'aoi', 'ran'];

const listItems = (): JSX.Element[] => {
  return list.map((item) => <span key={item}>{item}</span>);
};

const Component = (): JSX.Element => {
  return <div>{listItems()}</div>;
};

所管

勘違いしてた部分も振り返れたので良かった。


[参考]

ゆっくりアイカツ!見返す時間が欲しいよ〜