Typing Props and Params

Typing Props, State and Navigation Params

BookNest's BookCard types its props as { book: Book; onPress: (id: number) => void; compact?: boolean }, and resolveJsonModule checks booknest-data.json against the Book interface. For routes, npx expo start writes .expo/types/router.d.ts (Typed Routes), listing every valid href and typing /book/[id]'s id as a string. The catalog screen renders <BookCard book={item} compact="no" ... /> and pushes /books/${id}; the detail screen adds two more mistakes:

src/app/book/[id].tsx, with two type errorsJavaScript
import { useLocalSearchParams } from 'expo-router';
import { useState } from 'react';
import { Button, Text } from 'react-native';
import { findBook } from '@/data/books';
export default function BookScreen() {
  const { id } = useLocalSearchParams<'/book/[id]'>();
  const book = findBook(id);
  const [cart, setCart] = useState([]);
  if (!book) return <Text>No such book</Text>;
  return <Button title={`Add ${book.title}`} onPress={() => setCart([...cart, book.id])} />;
}
Output
$ npx tsc --noEmit
src/app/book/[id].tsx(8,25): error TS2345: Argument of type 'string' is not assignable to
parameter of type 'number'.
src/app/book/[id].tsx(12,70): error TS2322: Type 'number' is not assignable to type 'never'.
src/app/book/[id].tsx(12,79): error TS2322: Type 'number' is not assignable to type 'never'.
src/app/index.tsx(13,31): error TS2322: Type 'string' is not assignable to
type 'boolean | undefined'.
src/app/index.tsx(13,73): error TS2345: Argument of type '`/books/${number}`' is not
assignable to parameter of type 'RelativePathString | ExternalPathString | ... | { ...; }'.

Metro would have bundled all four. Convert text parameters, findBook(Number(id)); type empty state, useState<number[]>([]); pass compact as a boolean; fix the route to /book/. Then tsc exits 0. With React Navigation 407,918 directly (Installing React Navigation), you write the param list, { Book: { id: number } }, yourself.