devops2023-07-05·10 min·345/348

Ignoring TypeScript Errors During Next.js Build

How to handle TypeScript errors in next build including selective ignoring, CI configuration, and build-time workarounds

Ignoring TypeScript Errors During Next.js Build

Introduction

TypeScript is an invaluable tool for catching errors at edit time, but there are situations where strict type checking during next build becomes a blocker. Third-party type definitions may be outdated, generated code may have temporary type mismatches, or migrating a JavaScript project to TypeScript may require incremental adoption.

After inheriting a large Next.js project with over 200 TypeScript errors, I needed a way to build and deploy while systematically fixing errors over time. This post documents every approach to managing TypeScript errors during the build process.

Environment

  • OS: Windows 11
  • Node.js: v20.10.0
  • Next.js: 14.0.4
  • TypeScript: 5.3.3

Problem

The build failed with TypeScript errors:

Type error: Type '{ children: ReactNode; className?: string }' is not assignable to type 'IntrinsicAttributes & Props'.
  Property 'children' does not exist on type 'Props'.
Failed to compile

./src/components/Dashboard.tsx
TypeScript error in ./src/components/Dashboard.tsx(45,12):
Type 'null' is not assignable to type 'string'.
error - Failed to compile page: /dashboard
Error: TypeScript compilation failed with 247 errors

The entire build pipeline was blocked because of errors in files that were not related to the current change.

Analysis

Next.js uses fork-ts-checker-webpack-plugin to run TypeScript checking in a separate process during build. By default, it treats all type errors as build failures. There are several ways to control this behavior:

1. ignoreBuildErrors in next.config.js. Completely disables TypeScript checking during build.

2. @ts-ignore comments. Ignores specific lines in source files.

3. // @ts-expect-error comments. Similar to @ts-ignore but reports an error if the comment is unnecessary.

4. tsconfig.json strictness options. Adjusting strict, noUnusedLocals, and similar options.

Solution

Approach 1: Disable TypeScript checking during build (temporary)

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  // WARNING: Only use this as a temporary measure
  typescript: {
    // Set to true to ignore TypeScript errors during build
    // WARNING: This means type errors will NOT block deployment
    ignoreBuildErrors: false, // Keep this false for production
  },
}

module.exports = nextConfig

Approach 2: Selective error suppression with tsconfig

// tsconfig.json
{
  "compilerOptions": {
    "target": "es2017",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,  // Skip checking .d.ts files
    "strict": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "incremental": true,
    "noUnusedLocals": false,  // Don't error on unused locals
    "noUnusedParameters": false,  // Don't error on unused params
    "noFallthroughCasesInSwitch": true
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules", ".next", "out"]
}

Approach 3: Per-file error suppression

// @ts-nocheck
// Use at the top of a file to disable ALL type checking for that file
// Use sparingly - only for files being actively migrated

import React from 'react'

// This file has known type issues that are being fixed
export function LegacyComponent(props: any) {
  return 
{props.name}
}
// Selective suppression with @ts-ignore
function processValue(value: string | null) {
  // @ts-ignore - Temporary workaround for upstream type issue
  const result = value.toLowerCase()
  return result
}
// Better: use @ts-expect-error which catches unnecessary suppressions
function processValue(value: string | null) {
  // @ts-expect-error - TODO: Fix type narrowing
  const result = value.toLowerCase()
  return result
}

Approach 4: CI pipeline with error tolerance

# .github/workflows/build.yml
name: Build

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Install dependencies
        run: npm ci

      - name: Type check (warnings only)
        run: npx tsc --noEmit --pretty false || echo "TypeScript errors found"

      - name: Build
        run: npm run build

      - name: Type check (strict, for reporting)
        run: npx tsc --noEmit 2> tsc-errors.txt || true
        if: always()

      - name: Comment on PR with TypeScript errors
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs')
            const errors = fs.readFileSync('tsc-errors.txt', 'utf8')
            if (errors.trim()) {
              github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: context.issue.number,
                body: '## TypeScript Errors\n```\n' + errors.substring(0, 3000) + '\n```'
              })
            }

Approach 5: Gradual migration with allowJs

// tsconfig.json - For JavaScript to TypeScript migration
{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": false,  // Don't type-check .js files
    "strict": false,   // Start with relaxed settings
    "noEmit": true
  },
  "include": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"]
}
// tsconfig.strict.json - Use for new files
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "strict": true,
    "checkJs": true
  }
}

Lessons Learned

  1. Never permanently disable TypeScript checking. ignoreBuildErrors: true is a short-term escape hatch, not a long-term strategy.

  2. Use skipLibCheck: true for most projects. It skips type checking of declaration files, which are often the source of unfixable errors from third-party libraries.

  3. Fix errors incrementally. Add a CI step that counts TypeScript errors and tracks the trend over time.

  4. Prefer @ts-expect-error over @ts-ignore. @ts-expect-error fails if the underlying error is fixed, preventing stale comments.

  5. Track your TypeScript error count:

# Count current TypeScript errors
npx tsc --noEmit 2>&1 | grep "error TS" | wc -l

This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.