TypeScript Type Checking Discrepancy in Next.js: next lint
vs next build
A common pitfall in TypeScript-based Next.js projects arises from a discrepancy between the next lint
and next build
commands. Where your code passes the linting stage but fails at build time due to un noticed type errors.
The Problem
Let’s consider this minimal example:
// copied from: https://github.com/vercel/next.js/discussions/31439
type TestComponentProps = {
variable: 'someValue' | 'otherValue';
};
const TestComponent: React.FC<TestComponentProps> = ({ variable }) => {
return <div>{variable}</div>;
};
const Home = () => {
return <TestComponent variable="test" />;
};
export default Home;
Here, the TestComponent
expects a prop variable
of type 'someValue' | 'otherValue'
, but the Home
component mistakenly passes the string "test"
a value outside the expected union type.
What Happens?
- ✅
next lint
passes without errors - ❌
next build
fails with the following:
Type error: Type '"test"' is not assignable to type '"someValue" | "otherValue"'.
Why didn’t next lint
catch this?
Why This Happens
The reason lies in the differing goals of each command:
next lint
uses ESLint for code quality checks and style enforcement. By default, it doesn’t perform TypeScript type checking.next build
performs full compilation and strict type checks using the TypeScript compiler.
Use the TypeScript Compiler Separately
Run the TypeScript compiler in --noEmit
mode to catch all type errors early:
tsc --noEmit
This ensures full type checking independently of the build process and if you a lot of these errors then its much more easier to deal it with tsc --noEmit
otherwise you will have to run next build
again and again till all the issues are fixed
For further discussion, check out the original GitHub thread.