Skip to main content

Overview

The tsconfig.json file configures TypeScript for the portfolio template. It defines compiler options, type checking rules, and module resolution settings to ensure type safety and proper code analysis.

Configuration File

Here’s the complete TypeScript configuration:
tsconfig.json
{
  "extends": "astro/tsconfigs/strict",
  "compilerOptions": {
    "strictNullChecks": true,
    "allowJs": true,
    "jsx": "react-jsx",
    "jsxImportSource": "react",
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["./src/env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["dist"]
}

Configuration Breakdown

Extends

"extends": "astro/tsconfigs/strict"
Inherits Astro’s strict TypeScript configuration preset. This provides:
  • Strict type checking enabled by default
  • Optimal settings for Astro projects
  • Type support for .astro files
  • Recommended compiler options for modern development
The strict preset enables options like:
  • strict: true (enables all strict type checking)
  • noImplicitAny: true (error on implicit any types)
  • strictFunctionTypes: true (strict function type checking)
  • strictPropertyInitialization: true (ensure properties are initialized)

Compiler Options

strictNullChecks

"strictNullChecks": true
Enforces strict null and undefined checking. When enabled:
  • null and undefined are distinct types
  • Must explicitly check for null/undefined before using values
  • Prevents common runtime errors from null reference exceptions
Example:
// Error: Object is possibly 'null'
const name = user.name.toUpperCase();

// Correct: Check for null first
const name = user?.name?.toUpperCase() ?? "Unknown";

allowJs

"allowJs": true
Allows importing JavaScript files in TypeScript files. Benefits:
  • Gradual migration from JavaScript to TypeScript
  • Use JavaScript libraries without type definitions
  • Mix .js and .ts files in the same project
Example:
// Import JS file in TS file
import { helper } from "./utils.js";

jsx

"jsx": "react-jsx"
Configures JSX transformation mode. The react-jsx option:
  • Uses React 17+ automatic JSX runtime
  • No need to import React in every file
  • Smaller bundle sizes
  • Improved performance
Before (react):
import React from "react";

function Component() {
  return <div>Hello</div>;
}
After (react-jsx):
// No React import needed!
function Component() {
  return <div>Hello</div>;
}

jsxImportSource

"jsxImportSource": "react"
Specifies which library provides the JSX runtime. Set to react to use React’s JSX implementation. This works together with jsx: "react-jsx" to enable the automatic JSX runtime.

baseUrl

"baseUrl": "."
Sets the base directory for resolving non-relative module names. Combined with paths, this enables absolute imports from the project root.

paths

"paths": {
  "@/*": ["./src/*"]
}
Configures path aliases for cleaner imports. The @/* alias maps to the src/ directory. Without alias:
import { Button } from "../../../components/ui/Button";
import { formatDate } from "../../../lib/utils";
With alias:
import { Button } from "@/components/ui/Button";
import { formatDate } from "@/lib/utils";
Benefits:
  • Shorter, cleaner imports
  • No need to count ../ levels
  • Easier refactoring (moving files doesn’t break imports)
  • More maintainable codebase

Include and Exclude

include

"include": ["./src/env.d.ts", "**/*.ts", "**/*.tsx"]
Specifies which files TypeScript should process:
  • ./src/env.d.ts: Type definitions for environment variables
  • **/*.ts: All TypeScript files in the project
  • **/*.tsx: All TypeScript + JSX files
TypeScript will type-check all files matching these patterns.

exclude

"exclude": ["dist"]
Excludes the dist/ directory from type checking. This is where build output goes, so there’s no need to type-check compiled files.

How This Configuration Works Together

The configuration enables several powerful features:

1. React Components with Type Safety

// src/components/Button.tsx
interface ButtonProps {
  label: string;
  onClick?: () => void;
}

export function Button({ label, onClick }: ButtonProps) {
  return <button onClick={onClick}>{label}</button>;
}

2. Clean Imports with Path Aliases

// src/pages/index.astro
import { Button } from "@/components/Button";
import { formatDate } from "@/lib/utils";
import { projects } from "@/data/projects";

3. Strict Type Checking

// Error: Property 'x' does not exist on type 'User'
function getName(user: User) {
  return user.x; // Caught at compile time
}

// Error: Object is possibly 'null'
const length = user.name.length; // Caught by strictNullChecks

4. Automatic JSX Runtime

// No React import needed
export function Welcome() {
  return <h1>Welcome!</h1>;
}

Customization Guide

Adding More Path Aliases

"paths": {
  "@/*": ["./src/*"],
  "@components/*": ["./src/components/*"],
  "@lib/*": ["./src/lib/*"],
  "@styles/*": ["./src/styles/*"]
}
If you add path aliases to tsconfig.json, you may also need to configure them in your bundler (Vite, in Astro’s case). Check your astro.config.ts or bundler configuration.

Relaxing Type Checking

If strict mode is too restrictive, you can override specific options:
"compilerOptions": {
  "strictNullChecks": false,  // Disable null checks
  "noImplicitAny": false,     // Allow implicit any
  "strictFunctionTypes": false // Relax function type checking
}
Relaxing type checking reduces type safety and can lead to runtime errors. Only do this if absolutely necessary.

Adding Type Definitions

For libraries without TypeScript support:
  1. Create a types/ directory
  2. Add type definition files:
    // types/my-library.d.ts
    declare module "my-library" {
      export function doSomething(): void;
    }
    
  3. Include in tsconfig.json:
    "include": ["./src/env.d.ts", "./types/**/*", "**/*.ts", "**/*.tsx"]
    

Changing JSX Configuration

For other JSX libraries:
// For Preact
"jsx": "react-jsx",
"jsxImportSource": "preact"

// For Solid
"jsx": "preserve",
"jsxImportSource": "solid-js"

Including JavaScript Files in Type Checking

"compilerOptions": {
  "allowJs": true,
  "checkJs": true  // Type-check JS files too
}

Common Issues and Solutions

Path Alias Not Working

Problem: Imports using @/ show errors or don’t resolve. Solution:
  1. Ensure baseUrl is set to "."
  2. Restart your TypeScript server (VS Code: cmd+shift+p > “TypeScript: Restart TS Server”)
  3. Check that the file exists at the expected path

JSX Not Recognized

Problem: .tsx files show JSX syntax errors. Solution:
  1. Ensure jsx is set to "react-jsx"
  2. Ensure jsxImportSource is set to "react"
  3. File must have .tsx extension (not .ts)

Strict Null Check Errors

Problem: Lots of “Object is possibly ‘null’” errors. Solution:
  1. Use optional chaining: user?.name
  2. Use nullish coalescing: value ?? defaultValue
  3. Add explicit null checks:
    if (user !== null) {
      console.log(user.name);
    }
    

Learn More

Build docs developers (and LLMs) love