tsc
TSC (TypeScript Compiler) Tool Analysis
Overview
TSC is the TypeScript compiler that performs static type checking on TypeScript files. This analysis compares Lintro’s wrapper with core tsc behavior.
Core Tool Capabilities
- Static type checking with full TypeScript type system
- Config discovery:
tsconfig.jsonwithextendschain support - Build modes:
--buildfor composite projects,--watchfor development - Output: JavaScript emission, declaration files, sourcemaps
- Flags:
--strict,--noEmit,--skipLibCheck,--project,--target,--module,--moduleResolution,--paths,--baseUrl, and 100+ compiler options - Incremental compilation with
--incrementaland--tsBuildInfoFile - Project references for monorepo support
Lintro Implementation Analysis
✅ Preserved Features
- ✅ Invokes tsc with
--noEmit --pretty falsefor type checking without output - ✅ Respects native
tsconfig.jsoncompiler options (auto-discovered or via--project) - ✅ File targeting works even with tsconfig.json (see below)
- ✅ Respects tsconfig.json
include/exclude/filesscoping (#851) - ✅ TypeScript project references (
references) support (#803) - ✅ Multi-project monorepo discovery and per-project type checking (#805)
- ✅ Per-project framework detection in monorepos
- ✅ Supports
--strictmode toggle - ✅ Supports
--skipLibCheckfor faster checks (enabled by default) - ✅ File discovery for
*.ts,*.tsx,*.mts,*.cts - ✅ Intelligent command fallback: direct
tsc->bunx tsc->npx tsc - ✅ Parses tsc output into structured
ToolResultwith file/line/column/code
File Targeting Behavior
The Problem: Native tsc ignores CLI file arguments when tsconfig.json exists,
instead checking all files defined in the config’s include/files patterns.
Lintro’s Solution: By default, lintro respects your file selection even when
tsconfig.json exists. This is achieved by creating a temporary tsconfig that:
- Extends your project’s
tsconfig.json(preserving all compiler options) - Overrides
includeto target only the files you specified
# Check only specific files (default behavior - lintro respects file targeting)
lintro check src/utils.ts src/helpers.ts --tools tsc
# → Creates temp config extending tsconfig.json but only checking these 2 files
# Check all files defined in tsconfig.json (native behavior)
lintro check . --tools tsc --tool-options "tsc:use_project_files=True"
# → Uses tsconfig.json as-is, checks all files in include/files patterns
This gives you the best of both worlds:
- Default: Lintro-style file targeting with tsconfig.json compiler options
- Opt-in: Native tsconfig.json file selection when needed
Respecting tsconfig scoping (#851): When your tsconfig.json has an explicit
include, files, or exclude field, lintro now respects it — running
tsc --project <tsconfig> directly instead of generating a temp config that overrides
the scoping. This prevents false positives from files the project intentionally excludes
(e.g., vitest.config.ts).
Monorepo Support (#803, #805)
Lintro automatically discovers TypeScript sub-projects in monorepos:
- Project references: Follows
referencesarrays in tsconfig.json recursively - Tree walking: Discovers
tsconfig.jsonfiles in subdirectories - Deepest wins: When parent and child tsconfigs overlap, files are assigned to the deepest (most specific) tsconfig, preventing double-checking under conflicting compiler options
- Per-project framework detection: Astro/Vue/Svelte detection is scoped per sub-project, not globally
# Monorepo with project references — each sub-project checked independently
lintro check . --tools tsc
# → packages/api: tsc -p packages/api/tsconfig.json
# → packages/web: skipped (Vue detected, use vue-tsc)
# → packages/lib: tsc -p packages/lib/tsconfig.json
⚠️ Limited / Missing
Build & Watch Modes:
- ❌ No
--watchmode (continuous compilation) - ❌ No
--buildmode (composite project building) - ❌ No
--incrementalcaching (each run is fresh)
Output Generation:
- ❌ No JavaScript emission (always uses
--noEmit) - ❌ No declaration file generation (
--declaration,--declarationMap) - ❌ No sourcemap generation (
--sourceMap,--inlineSourceMap) - ❌ No output directory control (
--outDir,--outFile)
Compiler Options (config-file-only):
- ⚠️
target,module,moduleResolution- must be set in tsconfig.json - ⚠️
paths,baseUrl,rootDir,rootDirs- must be set in tsconfig.json - ⚠️
lib,types,typeRoots- must be set in tsconfig.json - ⚠️
esModuleInterop,allowSyntheticDefaultImports- must be set in tsconfig.json - ⚠️
jsx,jsxFactory,jsxFragmentFactory- must be set in tsconfig.json - ⚠️
experimentalDecorators,emitDecoratorMetadata- must be set in tsconfig.json - ⚠️ All other
compilerOptionsnot exposed via--tool-options
Advanced Features:
- ❌ No plugins configuration
- ❌ No
--generateTraceperformance profiling - ❌ No custom diagnostic formatting
- ❌ No
--listFiles,--listEmittedFilesintrospection
🚀 Enhancements
- ✅ Safe timeout handling (default 60s) with structured timeout result
- ✅ Auto config discovery prioritizes
tsconfig.jsonin working directory - ✅ Smart file targeting via temp tsconfig (preserves compiler options)
- ✅ Normalized
ToolResultwith parsed issues fromtsc_parser - ✅ Priority 82, tool type
LINTER | TYPE_CHECKER, same as mypy - ✅ Windows path normalization in parser output
- ✅ Graceful handling when tsc is not installed with helpful install hints
- ✅ Dependency error categorization - separates missing module errors from type errors
- ✅ Auto-install support - optionally install Node.js deps before running tsc
Dependency Error Handling
Lintro intelligently categorizes tsc errors to distinguish between actual type errors
and errors caused by missing dependencies (e.g., when node_modules is not installed).
Error Categories
Dependency errors (TS2307, TS2688, TS7016):
TS2307: Cannot find module ‘X’ or its corresponding type declarationsTS2688: Cannot find type definition file for ‘X’TS7016: Could not find a declaration file for module ‘X’
Type errors (all other codes):
- Actual TypeScript type checking issues in your code
Output Example
When dependency errors are detected, Lintro shows them separately with actionable guidance:
Results: tsc
├── Type errors: 3
│ └── src/utils.ts:15 - Type 'string' not assignable to 'number'
│ └── ...
└── Missing dependencies: 4
└── vite/client, react, @types/node, ...
Suggestions:
- Run 'bun install' or 'npm install'
- Use '--auto-install' flag
Auto-Install Dependencies
Use the --auto-install flag to automatically install Node.js dependencies before
running tsc:
# Auto-install deps then run tsc
lintro check src/ --tools tsc --auto-install
# Enable globally in config
# .lintro-config.yaml
execution:
auto_install_deps: true
Package manager preference:
bun install --frozen-lockfile(falls back tobun install)npm ci(falls back tonpm install)
Note: In Docker, dependencies are auto-installed by default when the container starts.
Usage Comparison
# Core tsc - type check only (checks all files in tsconfig.json)
tsc --noEmit
# Core tsc - with specific config
tsc --project tsconfig.app.json --noEmit
# Lintro wrapper - check specific files (respects file targeting)
lintro check src/utils.ts --tools tsc
# Lintro wrapper - check directory (finds all .ts/.tsx files)
lintro check src/ --tools tsc
# Lintro wrapper - use tsconfig.json file selection (native behavior)
lintro check . --tools tsc --tool-options "tsc:use_project_files=True"
# Lintro wrapper - enable strict mode override
lintro check src/ --tools tsc --tool-options "tsc:strict=True"
# Lintro wrapper - use specific config file
lintro check src/ --tools tsc --tool-options "tsc:project=tsconfig.build.json"
Configuration Strategy
- File targeting preserved: Lintro respects your file selection by default
- Compiler options inherited: All settings from
tsconfig.jsonare preserved - No config injection: Lintro cannot modify tsconfig.json settings; tool is “Native only”
- Tool options available:
tsc:project(string) - path to tsconfig.json filetsc:strict(bool) - enable--strictflagtsc:skip_lib_check(bool) - enable--skipLibCheck(default: true)tsc:use_project_files(bool) - use tsconfig.json’s include/files patterns instead of lintro’s file targeting (default: false)tsc:timeout(int) - execution timeout in seconds (default: 60)
- Config display:
lintro config -vshows parsed tsconfig.json compilerOptions
Priority and Conflicts
- Priority: 82 (runs after formatters/linters, before tests)
- Tool Type: LINTER | TYPE_CHECKER
- Conflicts: None
- Complements: oxlint, oxfmt, prettier (formatting/linting)
Recommendations
- Use Lintro when you want quick type checking integrated into a multi-tool workflow with normalized output and timeout safety.
- Use core tsc directly when you need:
- Watch mode for development (
tsc --watch) - Build mode for composite projects (
tsc --build) - Incremental compilation for large projects
- JavaScript/declaration file output
- Fine-grained compiler option control beyond tsconfig.json
- Watch mode for development (