Start an Astro project

Use TypeScript in Astro components

Type props and component code while remembering that the types disappear from runtime output.

Astro components support TypeScript out of the box. You don’t rename anything. You write TypeScript inside the component script of a normal .astro file, and it works.

The most common use is typing the props a component accepts. Here is a small heading component:

---
interface Props {
  title: string
  published?: boolean
}

const { title, published = false } = Astro.props
---

<h2>{title}</h2>
{published && <p>Published</p>}

The Props interface says what this component expects. A title that must be a string, and an optional published flag. Astro picks up the interface by name and applies it to Astro.props.

What you get

Two things. First, documentation. Open the component and you see its contract in the first lines. Hover the <Heading> tag where it’s used and the editor shows the same information.

Second, checks. Pass a number to title and the editor underlines it. Forget title and you get an error. Run astro check and the same errors show up in the terminal, so you can catch them in CI too.

What you don’t get

Types disappear when the code runs. TypeScript checks your code while you write it, then compiles to plain JavaScript. At runtime there is no interface Props.

This means a type does not validate anything that arrives from outside your code. A database response, a form submission, an environment variable, a JSON file you parse. If the JSON says title is a number, TypeScript won’t stop it. The annotation is a promise you made, not a check the program performs.

When data crosses a boundary you don’t control, validate it at runtime before treating it as the typed shape. Astro’s content collection schemas do exactly this for Markdown frontmatter, and we’ll use them later in the course.

Keep types close to what they describe

A small Props interface at the top of the component is usually clearer than a shared type in a distant file that only one component uses. Move a type out only when two or more components really share it.

Try this in your project: pass a number to title and watch the editor flag the call. Then, in the component script, JSON.parse() a string with the wrong shape and assign it to a typed variable. Nothing complains. That’s the difference between a type and a runtime check.

Lesson completed