Skip to content

fix(menubar,menu,tieredmenu,megamenu,contextmenu,panelmenu,breadcrumb,steps,tabmenu,splitbutton,dock,speeddial): enable generic type inference for model and slots#8495

Open
YevheniiKotyrlo wants to merge 2 commits intoprimefaces:masterfrom
YevheniiKotyrlo:fix/menu-family-generics

Conversation

@YevheniiKotyrlo
Copy link

@YevheniiKotyrlo YevheniiKotyrlo commented Mar 13, 2026

Defect Fixes

Fixes #8494
Fixes #4175

All menu-family components use MenuItem for their model prop and all slot scoped data. Developers who extend MenuItem with custom properties get no type safety — custom properties resolve to any via the [key: string]: any index signature instead of their declared types.

Same root cause as #8442DefineComponent's no-arg constructor prevents generic inference. Same fix pattern as #8444 (DataTable/DatePicker).

Related: #7426, #6041

Reproducer: StackBlitzbun run type-check (0 errors, typo undetected) → bun run patch && bun run type-check (TS2339 catches it)

Problem

interface MyMenuItem extends MenuItem {
  route?: string;
  badge?: number;
}

const items: MyMenuItem[] = [
  { label: 'Home', route: '/home', badge: 5 }
];
<Menubar :model="items">
  <template #item="{ item }">
    {{ item.route }}
    <!-- No error — `item.route` is `any` (from index signature), typo ships to production -->
  </template>
</Menubar>

After this fix, TypeScript infers T = MyMenuItem from the :model binding and flows it to all slots:

<Menubar :model="items">
  <template #item="{ item }">
    {{ item.route }}
    <!-- item.route is `string | undefined` — proper type from MyMenuItem -->
  </template>
</Menubar>

Changes

For each component (Menubar, Menu, TieredMenu, MegaMenu, ContextMenu, PanelMenu, Breadcrumb, Steps, TabMenu, SplitButton, Dock, SpeedDial):

  • [Component]Props<T extends MenuItem = MenuItem>model: T[]
  • [Component]Slots<T extends MenuItem = MenuItem> — all item-bearing slot parameters become T
  • Generic constructor: new <T extends MenuItem = MenuItem>(props: [Component]Props<T>) with $slots: [Component]Slots<T>
  • T defaults to MenuItem (not any) — menu components have a well-defined base type, and the [key: string]: any index signature on MenuItem is preserved for undeclared properties

Special cases:

  • Breadcrumb: home?: T prop also becomes generic
  • PanelMenu: headericon slot also receives item: T
  • SplitButton: uses menuitemicon slot name instead of itemicon
  • Menu, TieredMenu, ContextMenu: Methods interfaces preserved (toggle, show, hide)
  • Dock: icon (deprecated) and itemicon slots also receive item: T
  • SpeedDial: itemicon slot also receives item: T

What gets typed

Slot Before After
#item item MenuItem T
#itemicon / #menuitemicon item MenuItem T
#submenuicon item (where present) MenuItem T
#start / #end (Menubar) no change no change
PanelMenu #headericon item MenuItem T
Breadcrumb home prop MenuItem T

Scope / Impact

  • No breaking changes — backward compatible, T defaults to MenuItem
  • No runtime changes — types only (.d.ts files)
  • 12 components: Menubar, Menu, TieredMenu, MegaMenu, ContextMenu, PanelMenu, Breadcrumb, Steps, TabMenu, SplitButton, Dock, SpeedDial

Verification

Gate Result
pnpm run format:check PASS
pnpm run lint PASS
pnpm run test:unit Pre-existing failures only, 0 new
pnpm run build:packages Pre-existing Windows build issue (NODE_ENV= syntax), 0 new

Series

This is part of a series bringing generic type inference to all PrimeVue data components:

PR Components Status
#8444 DataTable, DatePicker Open
#8484 Select, MultiSelect, Listbox Open
#8485 Column (phantom of prop) Open
#8489 AutoComplete, CascadeSelect, DataView Open
#8490 Carousel, Galleria, Timeline Open
#8491 OrderList, PickList Open
#8493 VirtualScroller, SelectButton, InputChips Open
#8495 Menubar, Menu, TieredMenu, MegaMenu, ContextMenu, PanelMenu, Breadcrumb, Steps, TabMenu, SplitButton, Dock, SpeedDial This PR

After this series, every PrimeVue component with a collection prop will infer T from the binding and flow it to slots — giving developers full IDE autocomplete and compile-time type safety in templates.

@YevheniiKotyrlo YevheniiKotyrlo changed the title fix(types): enable generic type inference for menu-family components fix(menubar,menu,tieredmenu,megamenu,contextmenu,panelmenu,breadcrumb,steps,tabmenu,splitbutton): enable generic type inference for model and slots Mar 13, 2026
@YevheniiKotyrlo YevheniiKotyrlo changed the title fix(menubar,menu,tieredmenu,megamenu,contextmenu,panelmenu,breadcrumb,steps,tabmenu,splitbutton): enable generic type inference for model and slots fix(menubar,menu,tieredmenu,megamenu,contextmenu,panelmenu,breadcrumb,steps,tabmenu,splitbutton,dock,speeddial): enable generic type inference for model and slots Mar 14, 2026
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

Successfully merging this pull request may close these issues.

Menu-family components: generic T not inferred from model prop Menu: More flexible MenuItem types

1 participant