Writing and Running Your Code
Writing and Running Your Code
TypeScript is a toolchain, not just a language. This chapter covers how to configure, run, and maintain TypeScript in real projects.
Item 55: Use a Single tsconfig.json Source of Truth
Keep compiler settings in one place and share them across tools.
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"noUncheckedIndexedAccess": true
}
}If you need multiple configs, extend a base file:
// tsconfig.base.json
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true
}
}Item 56: Let tsc Type‑Check, Let the Bundler Emit
Use tsc --noEmit in CI and rely on your bundler (Next, Vite, Webpack) for output.
pnpm tsc --noEmitThis prevents conflicts in output settings and keeps builds fast.
Item 57: Use tsx or ts-node for Small Scripts
For CLI scripts and tooling:
pnpm add -D tsx
tsx scripts/generate.tsUse ts-node only if you need full TypeScript compiler behavior.
Item 58: Turn On Source Maps for Debugging
{
"compilerOptions": {
"sourceMap": true
}
}This makes stack traces and browser debugging map to TypeScript lines.
Item 59: Prefer @ts-expect-error Over @ts-ignore
@ts-expect-error fails if the error disappears, preventing stale ignores.
// @ts-expect-error: temporary migration workaround
legacyThing();Item 60: Add ESLint for Non‑Type Errors
TypeScript does not catch everything (e.g., unused vars, async mistakes). Linting fills the gap:
{
"extends": ["next", "next/core-web-vitals"]
}Item 61: Use isolatedModules for Babel/Vite Builds
If you transpile with Babel or SWC, turn this on:
{
"compilerOptions": {
"isolatedModules": true
}
}It prevents patterns that only tsc can handle (like const enum).
Item 62: Use Project References for Large Repos
Project references speed builds and enforce boundaries:
{
"references": [{ "path": "./packages/shared" }]
}Use composite: true in referenced projects.
Item 63: Include Type Tests in CI
Type tests catch API regressions without running code.
// type-tests.ts
expectType<Promise<User>>(fetchUser("1"));Item 64: Treat Compiler Errors as Design Feedback
When TypeScript complains, it's often a chance to simplify types or make APIs more precise. This mindset keeps your codebase healthy.
Key Takeaways
- Centralize compiler config and share it.
- Use
tsc --noEmitfor type checking. - Use a TS runtime for scripts (tsx/ts-node).
- Turn on source maps for debugging.
- Prefer
@ts-expect-errorwith reasons. - Lint for non-type issues.
- Use project references in large repos.
Next: strategies for migrating existing JavaScript to TypeScript.