Glint template type-checking reference — @glint/template, @glint/ember-tsc, @glint/tsserver-plugin for type-safe GTS templates in A3
From a3-pluginnpx claudepluginhub trusted-american/marketplace --plugin a3-pluginThis skill uses the workspace's default tool permissions.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
Glint provides TypeScript-powered type checking for Ember's GTS templates. A3 uses three Glint packages:
@glint/template v1.7.2 — Template type primitives@glint/ember-tsc v1.0.7 — CLI type checker (ember-tsc --noEmit)@glint/tsserver-plugin v2.0.8 — IDE integration (autocomplete, errors in templates)Without Glint, TypeScript only checks .ts files — templates are invisible to the type system. Glint extends TypeScript to understand GTS template syntax:
Signature interface@argName referencesEvery typed component defines a Signature interface that Glint enforces:
interface MyComponentSignature {
// Args: what the caller passes as @argName
Args: {
name: string; // Required — Glint errors if caller omits this
count?: number; // Optional — ? means caller can omit
onSave: () => void; // Function arg — Glint checks the type
};
// Blocks: what {{yield}} passes to the caller
Blocks: {
default: [item: MyModel, index: number]; // Positional params yielded
header: []; // Named block, no params
empty: []; // Named block for empty state
};
// Element: the root element type for ...attributes
Element: HTMLDivElement; // Glint checks that HTML attrs match this element
}
// Component definition
export default class UserCard extends Component<UserCardSignature> {
<template>
<div ...attributes> {{! Glint knows this is HTMLDivElement }}
{{@name}} {{! Glint knows this is string }}
{{@count}} {{! Glint knows this is number | undefined }}
{{yield @someData 0}} {{! Glint checks yield matches Blocks.default }}
</div>
</template>
}
// Usage — Glint catches errors at compile time:
<UserCard @name="John" /> {{! OK — count is optional }}
<UserCard @name={{42}} /> {{! ERROR: number not assignable to string }}
<UserCard /> {{! ERROR: missing required arg @name }}
<UserCard @name="John" @typo="x" /> {{! ERROR: @typo not in Args }}
Template-only components (no class) use module-level type annotations:
import type { TOC } from '@ember/component/template-only';
interface Signature {
Args: { label: string; color?: string };
Element: HTMLSpanElement;
}
const Badge: TOC<Signature> = <template>
<span class="badge bg-{{@color}}" ...attributes>
{{@label}}
</span>
</template>;
export default Badge;
import type { HelperLike } from '@glint/template';
// For helpers imported in templates:
type FormatDateHelper = HelperLike<{
Args: { Positional: [date: Date]; Named: { format?: string } };
Return: string;
}>;
import type { ModifierLike } from '@glint/template';
type TooltipModifier = ModifierLike<{
Args: {
Positional: [text: string];
Named: { placement?: 'top' | 'bottom' | 'left' | 'right' };
};
Element: HTMLElement;
}>;
For addons that don't ship Glint types, augment the registry:
// types/glint.d.ts
import type { HelperLike, ComponentLike } from '@glint/template';
declare module '@glint/environment-ember-loose/registry' {
export default interface Registry {
// Register a helper
t: HelperLike<{ Args: { Positional: [key: string]; Named: Record<string, unknown> }; Return: string }>;
// Register a component
FaIcon: ComponentLike<{ Args: { icon: string; prefix?: string }; Element: SVGElement }>;
// Register a modifier
on: ModifierLike<{ Args: { Positional: [event: string, handler: Function] }; Element: Element }>;
}
}
# Type-check all templates + TypeScript
ember-tsc --noEmit
# A3's lint:types script runs this:
pnpm lint:types # → ember-tsc --noEmit
The @glint/tsserver-plugin integrates with VS Code's TypeScript language service:
tsconfig.json, the plugin is configured:{
"compilerOptions": {
"plugins": [{ "name": "@glint/tsserver-plugin" }]
}
}
@args in templates@args, this.properties, and component names| Error | Cause | Fix |
|---|---|---|
Property '@foo' does not exist on Args | Typo or missing arg in signature | Add to Args interface or fix the typo |
Expected 1 argument, but got 0 | Required arg not passed | Pass the arg or make it optional with ? |
Type 'number' is not assignable to 'string' | Wrong arg type | Fix the value or update the signature |
Block ':default' yields 2 values but only 1 consumed | yield/block arity mismatch | Update the Blocks signature or the yield |
Element does not have attribute 'xyz' | ...attributes on wrong element type | Fix the Element type in signature |