Skip to content
edge-language-tools
Esc
navigateopen⌘Jpreview
On this page

The @types block

Declaring a template's interface.

A @types block is the template’s function signature, written in a comment — it works with plain Edge, requires zero runtime changes, and can never affect rendering. The body is an object literal or any TypeScript type expression.

{{--
@types {
  user: { name: string, email: string }
  posts: { title: string, body: string }[]
}
--}}

The common case: declare the props right where they’re used.

The body accepts any TypeScript type expression, so shared shapes live in real .ts files:

{{-- @types import('./shared/layout.types.ts').Props --}}
export interface Props {
  user: { name: string; avatarUrl: string }
  nav: { label: string; href: string }[]
}

Best once several templates share a shape — one interface, many templates.

Imports resolve through your project’s tsconfig.json, so path aliases work — including framework models:

{{-- @types { user: import('#models/user').User } --}}

The doc header: @name and @desc

The same comment can carry documentation — JSDoc for templates. @name takes the rest of its line; @desc runs until the next directive or the comment’s end:

{{--
@name User Card
@desc Displays a user card with title and body.
  Used on the profile and team pages.
@types {
  user: { name: string }
}
--}}

Editors surface all three together: hover @userCard (or the path string in @component('components/user_card', ...)) anywhere it’s used and you get the name, the description, and the props signature. The same card appears in the @ tag-completion popup, so a component library documents itself as you browse. Stock Edge ignores comments, so none of this touches rendering.

What’s inferred (never declared)

  • @let(total = items.length * 2)total: number
  • @each(item in items)item from the array’s element type
  • Narrowing inside @if(user.subscription) blocks
  • Edge globals (truncate, html.escape, case helpers, …) are pre-typed

Cross-file checking

  • @component('components/card', { title }) — the props object is checked against the component’s own @types; typos error at the caller
  • Supercharged shorthands (@formInput(...), @modal(...)) resolve through Edge’s filename-to-tag rules and get the same checking
  • @include('partials/nav') — the caller’s state must satisfy the partial’s declared types
  • Dynamic names (@include(someVar)) degrade gracefully to unchecked

Was this page helpful?