glint icon indicating copy to clipboard operation
glint copied to clipboard

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

Open jelhan opened this issue 2 years ago • 4 comments

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

jelhan avatar Nov 04 '23 12:11 jelhan

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?

dfreeman avatar Nov 04 '23 14:11 dfreeman

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

NullVoxPopuli avatar Nov 04 '23 15:11 NullVoxPopuli

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

jelhan avatar Nov 04 '23 16:11 jelhan

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.

dfreeman avatar Nov 04 '23 16:11 dfreeman