Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*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) #661

Open
NullVoxPopuli opened this issue Dec 31, 2023 · 5 comments

Comments

@NullVoxPopuli
Copy link
Contributor

Repro:

  • git clone [email protected]: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

@NullVoxPopuli NullVoxPopuli changed the title When using WithBoundArgs, Type instantiation is excessively deep and possibly infinite. When using WithBoundArgs, Type instantiation is excessively deep and possibly infinite (requiring glint-ignore/expect-error to move forward in a project) Dec 31, 2023
@NullVoxPopuli NullVoxPopuli changed the title When using WithBoundArgs, Type instantiation is excessively deep and possibly infinite (requiring glint-ignore/expect-error to move forward in a project) *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) Dec 31, 2023
@NullVoxPopuli
Copy link
Contributor Author

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

@NullVoxPopuli
Copy link
Contributor Author

Just ran in to this with a yielded component type, too

@NullVoxPopuli
Copy link
Contributor Author

NullVoxPopuli commented Mar 9, 2024

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 scrollToBottoms 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.

@boris-petrov
Copy link
Contributor

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. :)

@miguelcobain
Copy link

I found this issue when simply trying to conditionally apply a modifier:

<button type="button" {{(if @onClick (modifier on "click" @onClick))}}>
  Click
</button>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants