learn.colinkim.dev

Linting, formatting, and type checking in CI

Learn how to set up a TypeScript project with linting, formatting, and automated type checking.

A well-configured TypeScript project does more than compile. It lints for quality, formats code consistently, and checks types in CI.

Type checking vs compilation

tsc does two things: type checking and compilation. In many projects, a faster transpiler (esbuild, swc, Vite) handles compilation, while tsc is used for type checking only:

# Type check without emitting files
npx tsc --noEmit

# Compile with a fast transpiler
npx vite build

This separation is common because tsc compilation can be slow for large projects, while --noEmit type checking is fast.

Linting with ESLint

ESLint catches code quality issues that TypeScript does not:

pnpm add -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin

A minimal ESLint config (.eslintrc.json):

{
  "parser": "@typescript-eslint/parser",
  "plugins": ["@typescript-eslint"],
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended"
  ]
}

Run it:

npx eslint src/

ESLint and TypeScript complement each other. TypeScript catches type errors; ESLint catches style, correctness, and maintainability issues.

Formatting with Prettier

Prettier enforces consistent code formatting:

pnpm add -D prettier

A minimal Prettier config (.prettierrc):

{
  "semi": true,
  "singleQuote": false,
  "trailingComma": "all"
}

Run it:

npx prettier --check src/     # check formatting
npx prettier --write src/     # fix formatting

ESLint + Prettier

Use eslint-config-prettier to disable ESLint rules that conflict with Prettier:

pnpm add -D eslint-config-prettier
{
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "prettier"
  ]
}

Type checking in CI

Type checking should run in CI on every pull request:

# GitHub Actions example
name: Type Check
on: [pull_request]
jobs:
  type-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - run: pnpm install
      - run: npx tsc --noEmit

The --noEmit flag runs type checking without producing output files. It is fast and catches type errors.

{
  "scripts": {
    "typecheck": "tsc --noEmit",
    "lint": "eslint src/",
    "lint:fix": "eslint src/ --fix",
    "format": "prettier --write src/",
    "format:check": "prettier --check src/",
    "build": "tsc",
    "dev": "tsc --watch"
  }
}

What to carry forward

  • tsc --noEmit type-checks without compiling — use it in CI
  • use a fast transpiler (esbuild, Vite) for compilation in large projects
  • ESLint catches code quality issues that TypeScript does not
  • Prettier enforces consistent formatting
  • eslint-config-prettier prevents conflicts between ESLint and Prettier
  • type checking in CI catches type errors before they reach production

The next lesson covers migrating JavaScript projects to TypeScript.

Progress

Quick checks

No quick checks in this lesson.

Mark lesson manually or answer quick checks to track progress.