Skip to content

Infer event handler parameter types from event payloads #24

Description

@Sapu94

Summary

When defining event handler methods on frames using the dispatch pattern, parameter types should ideally be inferred from the known event payload:

local f = CreateFrame("Frame")
f:RegisterEvent("ENCOUNTER_END")
f:SetScript("OnEvent", function(self, event, ...)
    f[event](self, ...)
end)

function f:ENCOUNTER_END(encounterID, encounterName, difficultyID, groupSize, success) end
-- These params are untyped, but ENCOUNTER_END's payload is fully known

What works today

The inline SetScript("OnEvent", ...) path already infers event payload types via params<FrameEvent> when you narrow with if event == "ENCOUNTER_END":

f:SetScript("OnEvent", function(self, event, ...)
    if event == "ENCOUNTER_END" then
        local encounterID, encounterName = ... -- typed correctly
    end
end)

Users can also manually annotate with @param on each handler method, but this requires knowing the payload signature upfront.

The problem

There's no way to say "this method's parameter types come from the ENCOUNTER_END event payload" without spelling out every @param manually. The event payload data is already in the LS — it just can't be referenced from an annotation on a function definition.

Design challenges

  • Event payloads are a two-key lookup (event type + event name), e.g. FrameEvent + "ENCOUNTER_END". There's no clean way to express this as a single type expression.
  • params<F> extracts from function types, but individual events aren't types — they're string keys in the event registry.
  • Exposing each event as a standalone fun(...) alias (e.g. ENCOUNTER_END as a type) pollutes the type namespace with thousands of ALL_CAPS aliases for a niche use case.
  • Syntax like FrameEvent<"ENCOUNTER_END"> or params<FrameEvent<ENCOUNTER_END>> is arbitrary and doesn't generalize.
  • @type on function definitions doesn't currently propagate parameter types by name.

Possible directions

  1. @type on function definitions — Make @type SomeFunAlias on a function definition match parameter types by name. General mechanism, but needs events exposed as function-type aliases.
  2. New annotation (e.g. @handles FrameEvent "ENCOUNTER_END") — Explicit but event-specific.
  3. Auto-inference — When a method on a Frame-typed table matches a known event name, infer param types automatically. Clean UX but implicit/special-cased.
  4. Something else — Open to ideas for a syntax that feels natural and generalizes well.

No urgency — leaving this open for a good design to emerge.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions