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
@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.
- New annotation (e.g.
@handles FrameEvent "ENCOUNTER_END") — Explicit but event-specific.
- 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.
- 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.
Summary
When defining event handler methods on frames using the dispatch pattern, parameter types should ideally be inferred from the known event payload:
What works today
The inline
SetScript("OnEvent", ...)path already infers event payload types viaparams<FrameEvent>when you narrow withif event == "ENCOUNTER_END":Users can also manually annotate with
@paramon 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_ENDevent payload" without spelling out every@parammanually. The event payload data is already in the LS — it just can't be referenced from an annotation on a function definition.Design challenges
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.fun(...)alias (e.g.ENCOUNTER_ENDas a type) pollutes the type namespace with thousands of ALL_CAPS aliases for a niche use case.FrameEvent<"ENCOUNTER_END">orparams<FrameEvent<ENCOUNTER_END>>is arbitrary and doesn't generalize.@typeon function definitions doesn't currently propagate parameter types by name.Possible directions
@typeon function definitions — Make@type SomeFunAliason a function definition match parameter types by name. General mechanism, but needs events exposed as function-type aliases.@handles FrameEvent "ENCOUNTER_END") — Explicit but event-specific.No urgency — leaving this open for a good design to emerge.