Skip to main content

Overview

The SAAC Frontend template uses TypeScript 5.8.x with strict type checking enabled. The TypeScript configuration is split across three files for better organization.

Configuration Files

The template uses a project references setup with three TypeScript configuration files:
  1. tsconfig.json - Root configuration that references the other configs
  2. tsconfig.app.json - Configuration for application source code
  3. tsconfig.node.json - Configuration for Node.js tooling (Vite config)

Root Configuration

tsconfig.json
{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ]
}
The root tsconfig.json doesn’t contain any files itself. It only serves as an entry point that references the specialized configurations.

Application Configuration

The main TypeScript configuration for your React application:
tsconfig.app.json
{
  "compilerOptions": {
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "target": "ES2022",
    "useDefineForClassFields": true,
    "lib": ["ES2022", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "verbatimModuleSyntax": true,
    "moduleDetection": "force",
    "noEmit": true,
    "jsx": "react-jsx",

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "erasableSyntaxOnly": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedSideEffectImports": true
  },
  "include": ["src"]
}

Compiler Options Explained

Build Configuration

tsBuildInfoFile
string
Location for incremental build info cache. Stored in node_modules/.tmp to avoid cluttering the project root.
target
string
default:"ES2022"
The ECMAScript target version for compiled output. ES2022 includes features like top-level await and class fields.
lib
string[]
Type definitions to include:
  • ES2022: Modern JavaScript APIs
  • DOM: Browser APIs (document, window, etc.)
  • DOM.Iterable: Iterable DOM collections
module
string
default:"ESNext"
Module system to use. ESNext enables the latest ES module features.
skipLibCheck
boolean
default:"true"
Skip type checking of declaration files (.d.ts). Speeds up compilation significantly.

Bundler Mode Settings

Bundler mode ("moduleResolution": "bundler") is optimized for modern bundlers like Vite, webpack, and esbuild. It enables:
  • Importing TypeScript files directly (.ts, .tsx)
  • Resolution that matches how bundlers work
  • Better tree-shaking and optimization
This mode assumes a bundler will handle module resolution, not Node.js.
moduleResolution
string
default:"bundler"
Use bundler-specific module resolution algorithm.
allowImportingTsExtensions
boolean
default:"true"
Allow importing .ts and .tsx files directly in imports.
verbatimModuleSyntax
boolean
default:"true"
Ensure import type and export type are preserved. Improves tree-shaking.
moduleDetection
string
default:"force"
Treat all files as modules (even without imports/exports).
noEmit
boolean
default:"true"
Don’t emit JavaScript output. Vite handles transpilation, TypeScript only does type checking.

JSX Configuration

jsx
string
default:"react-jsx"
JSX transformation mode:
  • react-jsx: Modern automatic runtime (no need to import React)
  • react: Classic runtime (requires import React from 'react')
The react-jsx mode enables the new JSX transform introduced in React 17+, eliminating the need to import React in every file.

Strict Type Checking

strict
boolean
default:"true"
Enable all strict type checking options:
  • strictNullChecks
  • strictFunctionTypes
  • strictBindCallApply
  • strictPropertyInitialization
  • noImplicitThis
  • alwaysStrict
noUnusedLocals
boolean
default:"true"
Report errors on unused local variables.
noUnusedParameters
boolean
default:"true"
Report errors on unused function parameters.
erasableSyntaxOnly
boolean
default:"true"
Ensure only type-level TypeScript syntax is used (enforces proper separation of types and runtime code).
noFallthroughCasesInSwitch
boolean
default:"true"
Prevent fallthrough cases in switch statements.
noUncheckedSideEffectImports
boolean
default:"true"
Ensure all imports are used or explicitly marked as side-effect imports.
Strict mode catches many common errors but may require more explicit type annotations. This is intentional and leads to more maintainable code.

Node Configuration

Configuration for Node.js tooling files (like vite.config.ts):
tsconfig.node.json
{
  "compilerOptions": {
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
    "target": "ES2023",
    "lib": ["ES2023"],
    "module": "ESNext",
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "verbatimModuleSyntax": true,
    "moduleDetection": "force",
    "noEmit": true,

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "erasableSyntaxOnly": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedSideEffectImports": true
  },
  "include": ["vite.config.ts"]
}

Key Differences from App Config

The Node configuration differs from the app configuration in a few ways:
  1. Target: ES2023 instead of ES2022 (Node.js supports newer features)
  2. Lib: Only ES2023, no DOM types (Node.js environment)
  3. Include: Only vite.config.ts, not the entire src directory
This separation ensures:
  • Build tooling code doesn’t accidentally use browser APIs
  • App code doesn’t accidentally use Node.js APIs
  • Faster type checking (smaller scope per config)

Type Checking

During Development

Vite performs runtime transpilation only during development. Type checking happens:
  1. In your editor (via TypeScript language server)
  2. On demand when you run tsc manually
This approach keeps HMR fast. Type errors don’t block the dev server.

Before Production Build

The build command runs type checking before bundling:
package.json
"build": "tsc -b && vite build"
The tsc -b command:
  • Type checks all project references
  • Uses incremental compilation
  • Fails the build if type errors are found
Production builds will fail if there are any TypeScript errors. Fix type errors before deploying.

Path Aliases

To add path aliases, update tsconfig.app.json:
tsconfig.app.json
{
  "compilerOptions": {
    // ... other options
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"],
      "@components/*": ["./src/components/*"],
      "@utils/*": ["./src/utils/*"]
    }
  }
}
Remember to also configure matching aliases in vite.config.ts for runtime module resolution.

Type Declarations

The template includes a type declaration file:
src/vite-env.d.ts
/// <reference types="vite/client" />
This provides type definitions for:
  • import.meta.env (Vite environment variables)
  • Asset imports (images, SVGs, etc.)
  • Special Vite features

Adding Custom Type Declarations

Create additional .d.ts files in src/ for custom types:
src/custom.d.ts
declare module '*.svg' {
  import React from 'react'
  export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>
  const src: string
  export default src
}

declare module '*.png' {
  const content: string
  export default content
}

Common Customizations

Disable Strict Mode

Not recommended. Strict mode prevents many runtime errors.
tsconfig.app.json
{
  "compilerOptions": {
    "strict": false
  }
}

Allow JavaScript Files

tsconfig.app.json
{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": false
  }
}

Enable Decorators

tsconfig.app.json
{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

Resources

Build docs developers (and LLMs) love