Repository navigation
Stop generation when an interface redeclares isApplicableTo or getPriority - #4
Conversation
…ority The dispatcher always creates both methods, so a redeclaration rendered them twice and the generated file failed with TS2393. Skipping the redeclaration by name is not enough: its signature can differ from the rendered one, which breaks compilation or silently drops arguments. Reject any redeclaration on a Dispatchable interface or its base types, whatever the signature, with an error and exit code 1. Fixes #2
Why generation stops instead of checking signaturesIssue #2 proposes skipping
Why not check signatures? A check would have to compare parameters, the context type, return types and type predicates against what the dispatcher renders, and decide what to do with compatible variants such as the property form. Rendering the user's signature instead would add the same complexity. Either way, that is a lot of logic for a case with no benefit: these methods are already inherited from Why reject every redeclaration? One rule by name covers all signatures, needs no comparison logic, and is easy to explain. The fix for the user is to delete the declaration, which is also the workaround the issue already recommends. Why an error instead of the usual warning? The aim is that the user sees the cause immediately. A warning is easy to miss in build output, and the first visible symptom would be a missing dispatcher somewhere else. The cost:
If a real need to redeclare these methods comes up, the check can be relaxed later without breaking anyone. |
Fixes #2
Summary
Dispatchableitself may still declare both methods, and implementation classes still implement them. This differs from the issue's expected result of one generated copy of each; the reasoning is in the comment below.Evidence
Interface:
PaymentHandler extends Dispatchable<PaymentContext> { isApplicableTo(context: PaymentContext): boolean; pay(): string }Before: generation succeeds, and the dispatcher contains
isApplicableTotwice, so it fails to compile with TS2393.After: generation exits with 1 and prints nothing to stdout:
Tests before the implementation: 13 new tests failed (40 passed).
After: 53 of 53 pass. Typecheck, build, both examples and the package smoke test also pass, and
example/generatedhas no diff.The tests cover matching and differing signatures, overloads, the property form, generic and type alias bases, and a base listed either side of
Dispatchable.Merge Danger
Door: two-way
The check can be relaxed later without affecting anyone who has already removed their redeclarations.
Blast Radius: consumers
Projects that redeclare these methods now get an error instead of a dispatcher, and the registry and all other dispatchers are not generated until they remove the declaration. For a redeclaration on the interface itself or on a non-generic interface base, the output did not compile before, so nothing working is lost. For a generic or type alias base, the old result was a warning and no dispatcher while the rest of the generation carried on, so those projects go from a warning to a hard stop. This deserves a line in the release notes.
Not covered:
H extends Mid, whereMid extends Dispatchable<Ctx>, BaseandBasedeclares the method.