TYPESCRIPT CONFIG FINAL SOLUTION

Documentation for Developers

TypeScript Configuration Final Solution

🎯 The Problem

Angular template errors (like missing methods) were only visible in the terminal during build, but NOT visible in the IDE (no red underlines, no Problems panel entries).

❌ What We Tried (That Didn't Work)

Attempt 1: Remove files: [] from tsconfig.lib.json

Result: Created "File not found" errors for all inherited paths

Attempt 2: Add files: [] to tsconfig.json (IDE coordinator)

Result: Broke Angular Language Service - no template checking in IDE!

Attempt 3: Clear inherited paths with paths: {}

Result: Broke IDE module resolution - couldn't find any imports

✅ The Correct Solution (Final)

Key Insight: Three fixes required

  1. Template Level: lib-coordinator.json must have files: []
  2. VS Code Level: Disable enableProjectDiagnostics for monorepos
  3. Path Mappings: Avoid duplicate aliases pointing to same library
lib-coordinator.json  → Has files:[] + inherits all paths from base
libs/*/tsconfig.json  → Extends template + adds include patterns
tsconfig.lib.json     → Extends local coordinator + overrides paths to dist/

The Pattern:

0. tsconfig.templates/lib-coordinator.json (Shared Template)

{
  "extends": "../tsconfig.base.json",
  "compilerOptions": {
    "noEmit": true
  },
  "files": [],  // ← CRITICAL: Prevents inherited paths from being compiled as root files
  "angularCompilerOptions": {
    "strictTemplates": true
  }
}

Why files: [] in the template?

1. libs/*/tsconfig.json (IDE Coordinator)

{
  "extends": "../../tsconfig.templates/lib-coordinator.json",
  "compilerOptions": {
    "strict": true  // Library-specific rules
  },
  "include": ["src/**/*.ts"],  // ← REQUIRED: Overrides files:[], tells TS what to compile
  "exclude": ["src/**/*.spec.ts", "src/**/*.test.ts"]
}

Why include is required?

2. libs/*/tsconfig.lib.json (Build)

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "../../dist/libs/my-lib",
    "paths": {
      "@dependency": ["../../dist/libs/dependency/index"]  // dist/, not src/!
    }
  },
  "files": [],  // ← CRITICAL: Prevents "File not found" errors
  "include": ["src/**/*.ts"],
  "exclude": ["src/**/*.spec.ts", "src/**/*.test.ts"]
}

Why files: [] here?

🔍 How Angular Template Errors Work

For template errors to appear in the IDE:

  1. VS Code Angular Language Service must be enabled
  2. angularCompilerOptions.strictTemplates: true must be set
  3. The IDE config (tsconfig.json) must compile files (no files: [])
  4. TypeScript server and Angular Language Service must be restarted after config changes

Required Settings in .vscode/settings.json:

{
  "angular.forceStrictTemplates": true,
  "angular.experimental-ivy": true
}

Required Settings in tsconfig.templates/lib-coordinator.json:

{
  "angularCompilerOptions": {
    "strictTemplates": true,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true
  }
}

🚀 How to Restart After Config Changes

  1. Press Cmd+Shift+P
  2. Type: "TypeScript: Restart TS Server" → Enter
  3. Type: "Angular: Restart Language Service" → Enter
  4. If errors persist, restart VS Code entirely

Sometimes the TypeScript Language Service caches need to be cleared:

rm -rf .angular/cache .nx/cache dist/libs/*/tsconfig.tsbuildinfo

📊 The Complete Extends Chain

IDE Path:
tsconfig.json → lib-coordinator.json → tsconfig.base.json
                (no files:[])           (all paths)
                ↓
        Angular Language Service
        ✅ Sees templates
        ✅ Has path resolution
        ✅ Shows errors in IDE

Build Path:
tsconfig.lib.json → tsconfig.json → lib-coordinator.json → tsconfig.base.json
  (files:[])          (no files:[])    (no files:[])          (all paths)
  ↓
NX Build / ng-packagr
✅ Only compiles source
✅ Resolves deps from dist/
✅ No "file not found" errors

🎓 Key Lessons Learned

  1. files: [] location matters:

    • Template: YES files: [] (prevents inherited paths from being root files)
    • IDE config: Inherits from template, adds include (works for Angular Language Service)
    • Build config: Also has files: [] for explicit clarity
  2. include patterns override files: [] behavior:

    • files: [] alone says "compile nothing"
    • But include patterns say "actually, compile these files"
    • This is how we get both: no root file errors + template checking works
  3. Angular Language Service uses include, not files:

    • Having files: [] doesn't break Angular Language Service
    • It looks at include patterns to know what to compile for template checking
    • The key is having angularCompilerOptions in the extends chain
  4. VS Code enableProjectDiagnostics breaks monorepos:

    • typescript.tsserver.experimental.enableProjectDiagnostics: true is designed for small projects
    • In monorepos with 50+ libraries, it tries to load ALL configs simultaneously
    • Even with files: [], the diagnostic engine treats inherited paths as root files
    • Solution: Set to false in .vscode/settings.json
  5. Duplicate path aliases cause config resolution bugs:

    • Having multiple aliases pointing to the same library confuses TypeScript's config inheritance
    • Example: Both @ui-editor and @editor-ui pointing to libs/editor-ui/src/index
    • This prevents files: [] from template from being respected
    • Solution: Remove duplicate aliases OR add explicit files: [] to affected library's tsconfig.json
  6. Caching is aggressive:

    • Config changes often require full VS Code restart
    • "Restart TS Server" isn't always enough
    • Clear .angular/cache and .nx/cache when in doubt

🔧 Quick Reference

Config File Purpose Has files: []? Has paths? Include pattern?
tsconfig.base.json Workspace root No Yes (all libs → src/) No
lib-coordinator.json Template for IDE YES ✅ Inherits from base No (added locally)
libs/*/tsconfig.json IDE/Language Service Inherits from template Inherits from template YES (required)
libs/*/tsconfig.lib.json Build YES (explicit) Custom (deps → dist/) YES
libs/*/tsconfig.spec.json Tests Inherits from local Inherits from local YES

⚠️ Common Issues & Solutions

Issue 1: "File not found" errors persist after fixing template

Symptom: Errors only appear when using "Restart TS Server", disappear on VS Code restart

Cause: typescript.tsserver.experimental.enableProjectDiagnostics: true in .vscode/settings.json

Solution:

{
  "typescript.tsserver.experimental.enableProjectDiagnostics": false
}

This experimental setting was designed for small projects and doesn't handle monorepo inheritance chains well.


Issue 2: One specific library has errors, others don't

Symptom: Only one library (e.g., editor-ui) shows "File not found" errors

Possible Cause: Duplicate path aliases in tsconfig.base.json

Diagnosis:

# Check for duplicate aliases
grep "@your-lib" tsconfig.base.json

If you find duplicates like:

"@ui-editor": ["libs/editor-ui/src/index"],
"@editor-ui": ["libs/editor-ui/src/index"]

Solutions:

Option A: Remove duplicate (recommended)

# Remove @ui-editor, keep only @editor-ui
# Update all imports in codebase

Option B: Add explicit files: [] to affected library

// libs/editor-ui/tsconfig.json
{
  "extends": "../../tsconfig.templates/lib-coordinator.json",
  "files": [],  // ← Explicit override for this library
  "include": ["src/**/*.ts"]
}

✨ Verification Checklist

After applying this pattern, you should have:

Final Verification Commands:

# 1. Check that enableProjectDiagnostics is disabled
grep "enableProjectDiagnostics" .vscode/settings.json
# Should show: false

# 2. Check for duplicate aliases
grep -E '"@[^"]*".*libs/' tsconfig.base.json | sort | uniq -d
# Should show: nothing (no duplicates)

# 3. Restart TS Server and verify no errors
# Cmd+Shift+P → "TypeScript: Restart TS Server"
# Problems panel should be clean

📚 Related Documentation