Migrate a file at a time: allowJs lets .js and .ts mix, and tsc reports nothing inside .js. BookNest's cart-total.js, an untyped reduce over books.find(...).price, passed; renamed to .ts, it fails:
$ npx tsc --noEmit src/lib/cart-total.ts(1,27): error TS7006: Parameter 'ids' implicitly has an 'any' type. src/lib/cart-total.ts(1,32): error TS7006: Parameter 'books' implicitly has an 'any' type. src/lib/cart-total.ts(2,22): error TS7006: Parameter 'sum' implicitly has an 'any' type. src/lib/cart-total.ts(2,27): error TS7006: Parameter 'id' implicitly has an 'any' type. src/lib/cart-total.ts(2,52): error TS7006: Parameter 'b' implicitly has an 'any' type.
Typing ids and books clears these and exposes a real bug, "Object is possibly 'undefined'": a stale cart ID would have crashed. Handle it:
import type { Book } from '@/data/books';
export function cartTotal(ids: readonly number[], books: readonly Book[]): number {
return ids.reduce((sum, id) => sum + (books.find((b) => b.id === id)?.price ?? 0), 0);
}Then npm 2,036 pkg set scripts.typecheck="tsc --noEmit" adds a script; npm run typecheck exits 0. Type the boundaries first (props, routes, specs, environment), enable the strict API, and gate CI on the script. Never fix an error with any or // @ts-ignore, which switch off the checker exactly where it was needed.