TypeScript 6.0 flipped defaults and deprecated half the old config surface.
This post shows the exact patterns to migrate real projects without breaking builds.
1. Strict Mode Without Breaking Your Codebase
Most teams enabled strict manually. Now it is default, and legacy code explodes.
Before
{
"compilerOptions": {
"strict": false
}
}
function getUser(id) {
return fetch(`/api/users/${id}`).then(r => r.json())
}
After
{
"compilerOptions": {
"strict": true
}
}
function getUser(id: string): Promise<User> {
return fetch(`/api/users/${id}`).then(r => r.json())
}
The fix is not just flipping the flag. You add types at boundaries first. API calls, DB calls, external inputs. This removes 80% of implicit any errors fast.
2. ES2025 Target Without Legacy Polyfills
TypeScript no longer pretends you support Internet Explorer.
Before
{
"compilerOptions": {
"target": "es5"
}
}
async function load() {
return await Promise.resolve(42)
}
After
{
"compilerOptions": {
"target": "es2022"
}
}
async function load(): Promise<number> {
return 42
}
You stop generating bloated output. No downleveling. Smaller bundles. Faster builds. If you still need ES5, that is Babel’s job now, not TypeScript’s .
3. ESM First Instead of CommonJS Guessing
The module system finally matches reality. ESM everywhere.
Before
{
"compilerOptions": {
"module": "commonjs"
}
}
const express = require('express')
After
{
"compilerOptions": {
"module": "esnext",
"moduleResolution": "bundler"
}
}
import express from 'express'
This aligns with Node, Bun, Deno, and bundlers. If you still need CommonJS output, set it explicitly. No more implicit defaults.
4. Kill Relative Path Hell with Subpath Imports
Deep relative imports slow you down when navigating code.
Before
import { validate } from "../../../lib/validation"
import { User } from "../../../types/user"
After
{
"imports": {
"#/*": "./src/*"
}
}
import { validate } from "#/lib/validation"
import { User } from "#/types/user"
This removes cognitive overhead in large codebases. When you combine this with fast navigation patterns, it compounds with the techniques in this guide to reading large JavaScript codebases efficiently.
5. Replace Manual Map Initialization with getOrInsert
You probably wrote this pattern hundreds of times.
Before
const cache = new Map<string, number[]>()
if (!cache.has("users")) {
cache.set("users", [])
}
cache.get("users")!.push(1)
After
const cache = new Map<string, number[]>()
cache.getOrInsert("users", []).push(1)
Or with lazy computation:
cache.getOrInsertComputed("expensive", (key) => {
return compute(key)
})
This removes boilerplate and eliminates a common source of undefined errors.
6. Stop Installing Temporal Types
Date handling has been broken for years. TypeScript now ships Temporal types.
Before
npm install @types/temporal-polyfill
import { Temporal } from "@js-temporal/polyfill"
const now = Temporal.Now.instant()
After
const meeting = Temporal.PlainDateTime.from({
year: 2026,
month: 3,
day: 25,
hour: 14,
minute: 30
})
const end = meeting.add({ hours: 1 })
No extra types. No polyfill types mismatch. Cleaner setup.
7. Fix Import Assertions Before They Break in 7.0
This one will break your build later if you ignore it now.
Before
import data from "./data.json" assert { type: "json" }
After
import data from "./data.json" with { type: "json" }
The syntax changed at the spec level. TypeScript 6.0 warns. TypeScript 7.0 removes support.
8. Minimal tsconfig That Actually Works
Most configs are overcomplicated. This is enough for modern apps.
After
{
"compilerOptions": {
"target": "es2022",
"module": "esnext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"types": ["node"],
"lib": ["es2025", "dom"]
},
"include": ["src"]
}
Two important details most people miss:
-
"types": ["node"]fixes missing Buffer and process errors -
"lib": ["es2025"]enables new APIs like Temporal and RegExp.escape
This config is already aligned with TypeScript 7.0.
TypeScript 6.0 is not about features. It is a cleanup release that forces modern defaults and removes legacy paths .
Run tsc --noEmit, fix every warning, and your project is ready for the 10x faster compiler. The teams that do this now will not feel the 7.0 migration at all.
Top comments (0)