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 lintpasses without errors - ❌
next buildfails 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 lintuses ESLint for code quality checks and style enforcement. By default, it doesn’t perform TypeScript type checking.next buildperforms 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.