Setting up TypeScript
Configures TypeScript 7 in a Bun project.
Prerequisites
- Bun project
Steps
Install
bun add -d typescriptConfigure — Bun / server-side project
tsconfig.jsonat the project root
// tsconfig.json { "compilerOptions": { // Environment setup & latest features "lib": ["ESNext"], "target": "ESNext", "module": "Preserve", "moduleDetection": "force", "types": ["bun"], // Bundler mode "moduleResolution": "bundler", "allowImportingTsExtensions": true, "verbatimModuleSyntax": true, "erasableSyntaxOnly": true, "noEmit": true, // Best practices "strict": true, "skipLibCheck": true, "noFallthroughCasesInSwitch": true, "noUncheckedIndexedAccess": true, "noImplicitOverride": true, "exactOptionalPropertyTypes": true, }, "include": ["scripts"], }Configure — browser app (Vite / TanStack Start)
- Same base, plus DOM libs,
vite/clienttypes and path aliases verbatimModuleSyntaxis deliberately not set here — see the option reference below
// tsconfig.json { "compilerOptions": { // Environment setup & latest features "lib": ["ESNext", "DOM", "DOM.Iterable"], "target": "ESNext", "module": "Preserve", "moduleDetection": "force", "jsx": "react-jsx", "types": ["vite/client", "bun"], "paths": { "@/*": ["./src/*"] }, // Bundler mode "moduleResolution": "bundler", "allowImportingTsExtensions": true, // Enabling this in a TanStack Start app can result in the server bundles leaking into client bundles "verbatimModuleSyntax": false, // verbatimModuleSyntax would normally imply isolatedModules, so it has to be set directly "isolatedModules": true, "erasableSyntaxOnly": true, "noEmit": true, // Best practices "strict": true, "skipLibCheck": true, "noFallthroughCasesInSwitch": true, "noUncheckedIndexedAccess": true, "noImplicitOverride": true, "exactOptionalPropertyTypes": true, }, "include": ["src", "vite.config.ts"], }- Pair it with oxlint's
typescript/consistent-type-importsrule, which enforcesimport typewithout the bundling hazardverbatimModuleSyntaxcarries
// .oxlintrc.jsonc { "rules": { "typescript/consistent-type-imports": "error", }, }- Same base, plus DOM libs,
Add scripts to
package.json- The bundler emits the JavaScript, so
tsconly ever type-checks
{ "scripts": { "build": "bun --bun vite build && tsc --noEmit && oxlint ." } }- The bundler emits the JavaScript, so
Verification
-
bunx tsc --noEmitexits 0
References
- Announcing TypeScript 7.0 — native compiler, removed options, new defaults
- Announcing TypeScript 6.0 — where the default changes and deprecations landed first
- Bun: TypeScript 6 and 7 — Bun's recommended
tsconfig.json - TSConfig reference — every option
- Modules: choosing compiler options — bundler vs library vs Node presets
- TanStack Start: build from scratch
— why
verbatimModuleSyntaxmust stay off