Skip to main content
Astro provides first-class TypeScript support out of the box. This guide covers how to configure TypeScript in your Astro project for optimal type safety and developer experience.

Quick Start

Astro includes TypeScript support by default. No installation required - just start using .ts and .astro files.
1

Generate types

Run astro sync to generate TypeScript types for your content collections and integrations:
npx astro sync
2

Create tsconfig.json

Add a tsconfig.json file to your project root:
tsconfig.json
{
  "extends": "astro/tsconfigs/strict"
}
3

Start developing

Use TypeScript in your .astro, .ts, and .tsx files:
src/pages/index.astro
---
interface Props {
  title: string;
  count: number;
}

const { title, count } = Astro.props;
---
<h1>{title}</h1>
<p>Count: {count}</p>

TypeScript Configuration

Using Astro’s Presets

Astro provides three TypeScript presets to choose from:

Custom TypeScript Configuration

You can extend Astro’s presets with your own settings:
tsconfig.json
{
  "extends": "astro/tsconfigs/strict",
  "include": [".astro/types.d.ts", "**/*"],
  "exclude": ["dist"],
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@components/*": ["src/components/*"],
      "@layouts/*": ["src/layouts/*"]
    },
    "strictPropertyInitialization": false
  }
}
  • baseUrl: Base directory for resolving non-relative module names
  • paths: Path mapping for module resolution (like aliases)
  • target: ECMAScript target version (default: ES2022)
  • module: Module code generation (default: ESNext)
  • lib: Library files to include (default: ["ES2022"])
  • jsx: JSX code generation (Astro handles this automatically)
  • resolveJsonModule: Allow importing .json files
  • allowJs: Allow JavaScript files in your project

Include and Exclude Patterns

Control which files TypeScript processes:
tsconfig.json
{
  "extends": "astro/tsconfigs/strict",
  "include": [
    ".astro/types.d.ts",
    "**/*"
  ],
  "exclude": [
    "dist",
    "node_modules",
    ".astro"
  ]
}
Always include .astro/types.d.ts - this file contains generated types for content collections and integrations.

Type Checking

Astro doesn’t type-check during development for performance. Use these methods to check types:

During Development

Install the Astro VSCode extension for inline type checking.Configure your editor to show TypeScript errors:
.vscode/settings.json
{
  "astro.typescript.enabled": true
}

In CI/CD

Add type checking to your build process:
package.json
{
  "scripts": {
    "build": "astro check && astro build",
    "check": "astro check"
  }
}
- name: Type check
  run: npm run check

Generated Types

Astro automatically generates types for your project:

Content Collections

Types are generated for content collections in .astro/types.d.ts:
src/content/config.ts
import { defineCollection, z } from 'astro:content';

const blog = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string(),
    description: z.string(),
    pubDate: z.date(),
  }),
});

export const collections = { blog };
Use generated types in your code:
src/pages/blog/[...slug].astro
---
import { getCollection, type CollectionEntry } from 'astro:content';

type BlogPost = CollectionEntry<'blog'>;

const posts: BlogPost[] = await getCollection('blog');
---

Integration Types

Integrations can add their own type definitions. Run astro sync to generate them:
npx astro sync
Add astro sync to your prepare script to run it automatically on npm install:
package.json
{
  "scripts": {
    "prepare": "astro sync"
  }
}

Type Safety in Astro Files

Component Props

Define types for component props:
src/components/Card.astro
---
interface Props {
  title: string;
  description?: string;
  href: string;
}

const { title, description, href } = Astro.props;
---
<a href={href}>
  <h3>{title}</h3>
  {description && <p>{description}</p>}
</a>

Frontmatter Type Assertions

Use type assertions for complex data:
src/pages/about.astro
---
import type { Author } from '../types';

const author: Author = {
  name: 'Jane Doe',
  email: '[email protected]',
  bio: 'Developer and writer'
};
---

Global Types

Define global types in a .d.ts file:
src/types/global.d.ts
declare module '*.svg' {
  const content: string;
  export default content;
}

interface Window {
  analytics?: any;
}

Import Aliases

Configure path aliases for cleaner imports:
1

Configure tsconfig.json

tsconfig.json
{
  "extends": "astro/tsconfigs/strict",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@components/*": ["src/components/*"],
      "@layouts/*": ["src/layouts/*"],
      "@lib/*": ["src/lib/*"]
    }
  }
}
2

Use aliases in your code

src/pages/index.astro
---
import Layout from '@layouts/Layout.astro';
import Card from '@components/Card.astro';
import { formatDate } from '@lib/utils';
---
Astro provides a default @/* alias that maps to src/*. You can use this without additional configuration.

Framework-Specific TypeScript

React

src/components/Counter.tsx
import { useState, type FC } from 'react';

interface CounterProps {
  initial?: number;
}

const Counter: FC<CounterProps> = ({ initial = 0 }) => {
  const [count, setCount] = useState(initial);
  
  return (
    <button onClick={() => setCount(count + 1)}>
      Count: {count}
    </button>
  );
};

export default Counter;

Vue

src/components/Counter.vue
<script setup lang="ts">
interface Props {
  initial?: number;
}

const props = withDefaults(defineProps<Props>(), {
  initial: 0
});

const count = ref(props.initial);
</script>

Svelte

src/components/Counter.svelte
<script lang="ts">
  export let initial: number = 0;
  let count = initial;
</script>

<button on:click={() => count++}>
  Count: {count}
</button>

Troubleshooting

Run astro sync to regenerate types:
npx astro sync
If issues persist, delete .astro/types.d.ts and run sync again.
Ensure .astro/types.d.ts is included in your tsconfig.json:
tsconfig.json
{
  "include": [".astro/types.d.ts", "**/*"]
}
Restart your TypeScript server in your editor.
Verify your tsconfig.json has both baseUrl and paths configured:
tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@components/*": ["src/components/*"]
    }
  }
}
If you’re getting too many errors with strict mode, start with the base preset:
tsconfig.json
{
  "extends": "astro/tsconfigs/base"
}
Gradually enable strict options as you fix issues.

Best Practices

Use strict mode

Enable strict TypeScript checks to catch errors early

Run astro sync

Keep generated types up-to-date, especially after schema changes

Type component props

Always define interfaces for component props

Check in CI/CD

Add astro check to your CI pipeline

Next Steps

Content Collections

Learn about type-safe content collections

Astro Config

Configure your Astro project

Environment Variables

Type-safe environment variables

Editor Setup

Set up your editor for Astro

Build docs developers (and LLMs) love