0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

新人エンジニアが最初にハマる Next.js の型エラー10選

Posted at

新人エンジニアが最初にハマる Next.js の型エラー10選

はじめに

Next.js と TypeScript の組み合わせはとても強力ですが、最初に触れるエンジニアにとって「型エラー地獄」に陥ることも少なくありません。
この記事では、実際の開発現場で新人エンジニアがよく遭遇する型エラーを10個ピックアップし、原因と解決方法をわかりやすく解説します。


1. useState 初期値の型推論ミス

const [count, setCount] = useState();
setCount(1);

エラー: Argument of type 'number' is not assignable to parameter of type 'undefined'.

原因: 初期値を省略すると useStateundefined 型として推論する。
解決: 明示的に型か初期値を与える。

const [count, setCount] = useState<number>(0);

2. useEffect の依存配列に関数を入れてはいけない

useEffect(() => {
  doSomething();
}, [doSomething]);

エラー: React Hook useEffect has a missing dependency: 'doSomething'.

原因: 関数が再生成されるたびに依存関係が変わるため。
解決: useCallback で関数をメモ化。

const doSomething = useCallback(() => { ... }, []);

3. props の型を定義し忘れる

export default function Hello(props) {
  return <p>{props.name}</p>;
}

エラー: Property 'name' does not exist on type '{}'
解決:

type HelloProps = { name: string };
export default function Hello({ name }: HelloProps) {
  return <p>{name}</p>;
}

4. useRouter の query は常に string | string[] | undefined

const { query } = useRouter();
const id = query.id; // 型エラー

解決:

const id = Array.isArray(query.id) ? query.id[0] : query.id ?? "";

5. params 型の不一致(App Router)

export default function Page({ params }: { params: { id: number } }) {
  return <div>{params.id}</div>;
}

エラー: "number" is not assignable to type "string"
原因: ルートパラメータは常に string として渡される。
解決:

export default function Page({ params }: { params: { id: string } }) {
  return <div>{params.id}</div>;
}

6. APIレスポンスの型ミスマッチ

const res = await fetch("/api/data");
const data: DataType = await res.json();

エラー: Type 'any' is not assignable to type 'DataType'.
解決: as を使うか、Zodなどで型を検証。

const data = (await res.json()) as DataType;

7. children の型を未定義

const Layout = ({ children }) => <main>{children}</main>;

エラー: Property 'children' does not exist on type '{}'
解決:

type LayoutProps = { children: React.ReactNode };
const Layout = ({ children }: LayoutProps) => <main>{children}</main>;

8. map の key に number を直接使う

{items.map((item, i) => (
  <div key={i}>{item.name}</div>
))}

警告: Do not use array index as key
対策: 一意なIDを使う。

{items.map(item => <div key={item.id}>{item.name}</div>)}

9. 非同期関数の戻り値を直接コンポーネントに使う

const data = fetchData();
return <p>{data.title}</p>;

エラー: Property 'title' does not exist on type 'Promise<Data>'.
解決:

const [data, setData] = useState<Data | null>(null);
useEffect(() => { fetchData().then(setData); }, []);

10. useRef 初期値に null を与えない

const inputRef = useRef<HTMLInputElement>();
inputRef.current?.focus();

エラー: Expected 1 arguments, but got 0.
解決:

const inputRef = useRef<HTMLInputElement>(null);

まとめ

TypeScript のエラーは「なぜ型がそう推論されたか」を理解すると一気に楽になります。
型を“敵”ではなく“相棒”として扱えるようになると、Next.js の開発体験は劇的に向上します。

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?