TypeScript

Astro ships with built-in support for TypeScript. You can import .ts and .tsx files in your Astro project, write TypeScript code directly inside your Astro component, and even use an astro.config.ts file if you like.

Astro doesn’t perform any type checking itself. Type checking should be taken care of outside of Astro, either by your IDE or through a separate script. The Astro VSCode Extension automatically provides TypeScript hints and errors in your open files.

It is strongly recommended that you create a tsconfig.json file in your project, so that tools like Astro and VSCode know how to understand your project. Some features (like npm package imports) aren’t fully supported in TypeScript without a tsconfig.json file.

Some TypeScript configuration options require special attention in Astro. Below is our recommended starter tsconfig.json file, which you can copy-and-paste into your own project. Every astro.new template includes this tsconfig.json file by default.

tsconfig.json
// Example: starter tsconfig.json for Astro projects
{
  "compilerOptions": {
    // Enable top-level await and other modern ESM features.
    "target": "ESNext",
    "module": "ESNext",
    // Enable node-style module resolution, for things like npm package imports.
    "moduleResolution": "node",
    // Enable JSON imports.
    "resolveJsonModule": true,
    // Enable stricter transpilation for better output.
    "isolatedModules": true,
    // Astro will directly run your TypeScript code, no transpilation needed.
    "noEmit": true
  }
}

Additionally, our templates include an env.d.ts file inside the src folder to provide Vite’s client types to your project:

env.d.ts
/// <reference types="astro/client" />

Optionally, you can delete this file and instead add the types setting to your tsconfig.json:

tsconfig.json
{
  "compilerOptions": {
    "types": ["astro/client"]
  }
}

If your project uses a UI framework, additional settings depending on the framework might be needed. Please see your framework’s TypeScript documentation for more information. (Vue, React, Preact, Solid)

Use explicit type imports and exports whenever possible.

import { SomeType } from './script';
import type { SomeType } from './script';

This way, you avoid edge cases where Astro’s bundler may try to incorrectly bundle your imported types as if they were JavaScript.

In your .tsconfig file, you can instruct TypeScript to help with this. The importsNotUsedAsValues setting can be set to error. Then, TypeScript will check your imports and tell you when import type should be used.

tsconfig.json
{
  "compilerOptions": {
    "importsNotUsedAsValues": "error",
  }
}

Astro supports import aliases that you define in your tsconfig.json & jsconfig.json paths configuration. Read our guide to learn more.

src/pages/about/nate.astro
---
import HelloWorld from '@components/HelloWorld.astro';
import Layout from '@layouts/Layout.astro';
---
tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@components/*": ["src/components/*"],
      "@layouts/*": ["src/layouts/*"]
    }
  }
}

Astro supports typing your component props via TypeScript. To enable, export a TypeScript Props interface from your Astro component. The Astro VSCode Extension will automatically look for the Props export and give you proper TS support when you use that component inside another template.

src/components/HelloProps.astro
---
export interface Props {
  name: string;
  greeting?: string;
}
const { greeting = 'Hello', name } = Astro.props;
---
<h2>{greeting}, {name}!</h2>

Astro provides JSX type definitions to check that your markup is using valid HTML attributes. You can use these types to help build component props. For example, if you were building a <Link> component, you could do the following to mirror the default HTML attributes in your component’s prop types.

src/components/Link.astro
---
export type Props = astroHTML.JSX.AnchorHTMLAttributes;
const { href, ...attrs } = Astro.props;
---
<a {href} {...attrs}>
  <slot />
</a>

It is also possible to extend the default JSX definitions to add non-standard attributes by redeclaring the astroHTML.JSX namespace in a .d.ts file.

src/custom-attributes.d.ts
declare namespace astroHTML.JSX {
  interface HTMLAttributes {
    'data-count'?: number;
    'data-label'?: string;
  }
}

To see type errors in your editor, please make sure that you have the Astro VS Code extension installed. Please note that the astro start and astro build commands will transpile the code with esbuild, but will not run any type checking. To prevent your code from building if it contains TypeScript errors, change your “build” script in package.json to the following:

package.json
  "scripts": {
    "build": "astro build",
    "build": "astro check && tsc --noEmit && astro build",
  },

📚 Read more about .ts file imports in Astro. 📚 Read more about TypeScript Configuration.

Errors Typing multiple JSX frameworks at the same time

Section titled Errors Typing multiple JSX frameworks at the same time

An issue may arise when using multiple JSX frameworks in the same project, as each framework requires different, sometimes conflicting, settings inside tsconfig.json.

Solution: Set the jsxImportSource setting to react (default), preact or solid-js depending on your most-used framework. Then, use a pragma comment inside any conflicting file from a different framework.

For the default setting of jsxImportSource: react, you would use:

// For Preact
/** @jsxImportSource preact */

// For Solid
/** @jsxImportSource solid-js */

Vue components are mistakenly typed by the @types/react package when installed

Section titled Vue components are mistakenly typed by the @types/react package when installed

The types definitions from the @types/react package are declared globally and therefore will be mistakenly used to typecheck .vue files when using Volar.

Status: Expected behavior.

Solution: There’s currently no reliable way to fix this, however a few solutions and more discussion can be found in this GitHub discussion.