profile.edge (what you write)

{{--
@types {
  user: { name: string; bio: string }
  items: string[]
}
--}}

<h1>{{ user.nmae }}</h1>
@let(total = items.length * 2)
<p>{{ total }}</p>
@each(item in items)
  <li>{{ item }}</li>
@end

profile.edge.ts (what TypeScript sees)

export {}
// ...ambient Edge globals (truncate, html, ...)

type __Types = {
  user: { name: string; bio: string }
  items: string[]
}
declare const state: __Types

;(async () => {
  const { user, items } = state

  ;( user.nmae )
  let total = items.length * 2
  ;( total )
  for (const item of items) {
    ;( item )
  }
})()
Hover or tap any highlighted expression. Both sides share byte offsets, so a diagnostic on the right lands on the exact characters on the left.