typed-ember / glint

TypeScript powered tooling for Glimmer templates
https://typed-ember.gitbook.io/glint
MIT License
109 stars 51 forks source link

{{#each-in}} breaks if used with a Map #645

Open jelhan opened 11 months ago

jelhan commented 11 months ago

The value of {{#each-in}} has an unexpected type if being used with a Map. Even trying to render the value in the template throws an error.

Simple reproduction:

import Component from '@glimmer/component';

export default class PlaygroundComponent extends Component {
  map: Map<string, number> = new Map([
    ['a', 1],
    ['b', 2],
    ['c', 3],
  ]);
{{#each-in this.map as |key value|}}
  {{key}}
  {{value}}
{{/each-in}}
app/components/playground.hbs:3:3 - error TS2345: Only primitive values and certain DOM objects (see `ContentValue` in `@glint/template`) are usable as top-level template content.
  Argument of type 'number | ((callbackfn: (value: number, key: string, map: Map<string, number>) => void, thisArg?: any) => void) | (() => IterableIterator<[string, number]>) | ... 6 more ... | ((key: string) => boolean)' is not assignable to parameter of type 'ContentValue'.
    Type '(callbackfn: (value: number, key: string, map: Map<string, number>) => void, thisArg?: any) => void' is not assignable to type 'ContentValue'.

3   {{value}}
    ~~~~~~~~~

Please note that it is working fine if using a POJO instead of a Map.

typescript: 5.2.2 @glint/template: 1.2.1

dfreeman commented 11 months ago

Neither the Guides nor the API docs suggest that each-in handles Maps specially, from what I can see. Can you point to documentation for that?

NullVoxPopuli commented 11 months ago

The guides and api docs are underspecified.

It makes sense that you'd want to allow all iterables, and each/each-in do work with all iterables

jelhan commented 11 months ago

Neither the Guides nor the API docs suggest that each-in handles Maps specially, from what I can see. Can you point to documentation for that?

Support was added in Ember 3.2.0. It was considered a bug fix. Please find details in the changelog: https://github.com/emberjs/ember.js/blob/main/CHANGELOG.md#v320-may-31-2018

dfreeman commented 11 months ago

In that case a PR to account for the behavior would be welcome

The guides and api docs are underspecified

Given that the guides talk about each-in by way of comparison to Object.keys and for...in loops, both of which are not iterable-aware, I'd say they're more than underspecified and rather actively misleading.