// This module is responsible for augmenting the upstream definitions of entities that interact // with templates to include the information necessary for Glint to typecheck them. import { ComponentLike, HelperLike, ModifierLike } from '@glint/template'; import { Context, FlattenBlockParams, HasContext, TemplateContext, } from '@glint/template/-private/integration'; import { ComponentSignatureArgs, ComponentSignatureBlocks, ComponentSignatureElement, } from '@glint/template/-private/signature'; ////////////////////////////////////////////////////////////////////// // Components import '@ember/component'; import '@ember/component/template-only'; import '@glimmer/component'; type ComponentContext = TemplateContext< This, ComponentSignatureArgs['Named'], FlattenBlockParams>, ComponentSignatureElement >; declare module '@glimmer/component' { export default interface Component extends InstanceType> { [Context]: ComponentContext; } } declare module '@ember/component' { export default interface Component extends InstanceType> { [Context]: ComponentContext; } } interface TemplateOnlyComponentInstance extends InstanceType> { [Context]: ComponentContext; } // As with other abstract constructor types, this allows us to provide a class // and therefore have InstanceType work as needed, while forbidding construction // by end users. type TemplateOnlyConstructor = abstract new () => TemplateOnlyComponentInstance; declare module '@ember/component/template-only' { export interface TemplateOnlyComponent extends TemplateOnlyConstructor {} } ////////////////////////////////////////////////////////////////////// // Helpers import '@ember/component/helper'; declare module '@ember/component/helper' { export default interface Helper extends InstanceType> {} } ////////////////////////////////////////////////////////////////////// // Modifiers import 'ember-modifier'; declare module 'ember-modifier' { export default interface ClassBasedModifier extends InstanceType> {} } ////////////////////////////////////////////////////////////////////// // Routes and Controllers import Controller from '@ember/controller'; import Route from '@ember/routing/route'; type ModelForRoute = Awaited>; type ModelField = { model: T }; declare module '@ember/routing/route' { export default interface Route { [Context]: TemplateContext< Controller & ModelField>, ModelField>, {}, null >; } } declare module '@ember/controller' { export default interface Controller { [Context]: TemplateContext, {}, null>; } } ////////////////////////////////////////////////////////////////////// // Rendering Tests import '@ember/test-helpers'; import 'ember-cli-htmlbars'; type TestTemplate = abstract new () => HasContext>; declare module '@ember/test-helpers' { export function render(template: TestTemplate): Promise; } // Declaring that `TemplateFactory` is a valid `TestTemplate` prevents vanilla `tsc` from freaking out // about `hbs` not returning a valid type for `render`. Glint itself will never see `hbs` get used, as // it's transformed to the template DSL before typechecking. declare module 'ember-cli-htmlbars' { interface TemplateFactory extends TestTemplate {} }