glint icon indicating copy to clipboard operation
glint copied to clipboard

Allow inline component signatures on first-class, template-only components

Open ef4 opened this issue 3 years ago • 2 comments
trafficstars

Using the ember-template-imports glint environment, given:

import Component from '@glimmer/component';

const Greeting = <template>{{@message}}</template>;

export default class Usage extends Component {
  <template><Greeting @message="hello" /></template>
}

both the caller and callee treat @mesage as a type error. I can manually provide the "outside" type to make the caller happy:

import Component from '@glimmer/component';
import { ComponentLike } from '@glint/template';

const Greeting: ComponentLike<{ Args: { message: string } }> = <template>{{@message}}</template>;

export default class Usage extends Component {
  <template><Greeting @message="hello" /></template>
}

But I can't find a way to provide the "inside" type to make the callee happy.

ef4 avatar Aug 20 '22 02:08 ef4

Documenting the explanation I was given in discord. You can get this correct today if you assign to a local variable:

import type { TemplateOnlyComponent } from '@ember/component/template-only';
import Component from '@glimmer/component';

const Greeting: TemplateOnlyComponent<{ Args: { message: string } }> = <template>{{@message}}</template>;

export default class Usage extends Component {
  <template><Greeting @message="hello" /></template>
}

What we don't have is a syntax to do it inline, especially for use with export default.

ef4 avatar Aug 20 '22 03:08 ef4

We've thrown around the idea (in both Framework and TS contexts) of making something like this work:

interface GreetingSig: { Args: { message: string } }

const Greeting = <template type:signature={GreetingSig}>
  {{@message}}
</template>;

That would nicely solve the export default shorthand as well:

interface GreetingSig: { Args: { message: string } }

<template type:signature={GreetingSig}>
  {{@message}}
</template>

We could possibly generalize to allow arbitrary type expressions between those top-level curlies in the XML namespace position, but that seems like an unnecessary complexity initially: better to stick with just referencing an in-scope binding of the appropriate sort (here: a type).

chriskrycho avatar Aug 21 '22 23:08 chriskrycho