*Like-bug: (ModifierLike, ComponentLike, etc?) When using WithBoundArgs, Type instantiation is excessively deep and possibly infinite (requiring glint-ignore/expect-error to move forward in a project)
NullVoxPopuli opened this issue · 5 comments
Repro:
git clone git@github.com:NullVoxPopuli/limber.git
cd limber
git checkout e6088f30e7036fd2bfe096e7a6c2f93c78e0e18b
pnpm build
cd apps/repl
pnpm lint:types
Error:
app/components/limber/menu.gts:118:18 - error TS2589: Type instantiation is excessively deep and possibly infinite.
118 Button=(component PlainTrigger menu=menu trigger=p.hook)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For this component, Menu, I've specified:
const Menu: TOC<{
Element: HTMLDivElement;
Args: {
inline?: boolean;
};
Blocks: {
trigger: [
{
menu: MenuTypes.Menu;
isOpen: boolean;
Default: WithBoundArgs<typeof DefaultTrigger, 'menu' | 'trigger'>;
Button: WithBoundArgs<typeof PlainTrigger, 'menu' | 'trigger'>;
},
];
options: [button: WithBoundArgs<typeof Button, 'item'>];
};
}> = <template>
and PlainTrigger is:
const PlainTrigger: TOC<{
Element: HTMLButtonElement;
Args: {
menu: MenuTypes.Menu;
trigger: ModifierLike<{ Element: HTMLButtonElement }>;
};
Blocks: {
default: [MenuTypes.Menu];
};
}> = <template>
<@menu.Button {{@trigger}} ...attributes>
{{yield @menu}}
</@menu.Button>
</template>;
and the menu types are:
declare module 'ember-headlessui/components/menu' {
import { ComponentLike } from '@glint/template';
export type Element<T extends HTMLButtonElement | HTMLAnchorElement> = ComponentLike<{
Element: T;
Args: { tagName?: 'button' };
Blocks: { default: [] };
}>;
export type Item = ComponentLike<{
Element: HTMLDivElement;
Blocks: { default: [{ Element: Element }] };
}>;
export type Items = ComponentLike<{
Element: HTMLDivElement;
Blocks: { default: [{ Item: Item }] };
}>;
export interface Menu {
isOpen: boolean;
Items: Items;
Button: ComponentLike<{
Element: HTMLButtonElement;
Blocks: { default: [] };
}>;
}
export default ComponentLike<{
Blocks: { default: [Menu] };
}>;
}
idk what the solution here is, but this feels undebuggable
I changed my args to my tiny components to be "any" and the issue went away.
Issue present
menu: MenuTypes.Menu;
trigger: ModifierLike;
Issue gone:
menu: MenuTypes.Menu;
trigger: any;
So.. that strongly looks like a bug in how the types for (component)
interact with the ModifierLike type
Just ran in to this with a yielded component type, too
Another repro:
import Component from '@glimmer/component';
import { modifier } from 'ember-modifier';
import type { ModifierLike } from '@glint/template';
class Scroller extends Component<{ Element: HTMLDivElement; Blocks: { default: [scrollToBottom: ModifierLike<{ }>]}}> {
declare withinElement: HTMLDivElement;
ref = modifier(( el: HTMLDivElement ) => {
this.withinElement = el;
});
<template>
<div ...attributes {{this.ref}}>
{{yield (modifier scrollToBottom this.withinElement)}}
</div>
</template>
}
Error:
Diagnostics:
1. glint: Type instantiation is excessively deep and possibly infinite. [2589]
I have another error because scrollToBottom
s usage isn't correct (yet), but the use of a ModifierLike
or any *Like should not cause infinite type evaluation, yeah?
I also meant to not use ModifierLike
in this situation, so ignore that.
For some reason updating to 1.4.0 from 1.3.0 fixed the (only) case I have in my codebase of this issue. I'm not using template-imports (which is the only change according to the changelog) so I'm not sure how that might have had an effect... but that's that. :)
I found this issue when simply trying to conditionally apply a modifier:
<button type="button" {{(if @onClick (modifier on "click" @onClick))}}>
Click
</button>