Conversation
…irectional assignment
f5a6e91 to
77548ad
Compare
1d09fbf to
5f5cc8f
Compare
| f3 = givesNarrow; // ✓ | ||
| ``` | ||
|
|
||
| > **Note:** The `eslint-disable` is intentional. `any` here is _not_ infectious: it is scoped to a single callback's parameter position and does not propagate to callers. The enclosing external APIs re-impose their own parameter types at each use site, so type safety is preserved where values actually flow. Prefer `unknown` or `never` when only one direction applies; reach for `any` only when both apply to the same parameter position. |
There was a problem hiding this comment.
I'm not sure about how this guideline is framed.
This note says that this is safe because "The enclosing external APIs re-impose their own parameter types at each use site", and indeed that is why this pattern is safe in the rare case where we've used it.
But this statement is not true of all situations where you might be tempted to use any to get around incompatible type expectations. "callback parameter types constrained by bidirectional assignment" may describe scenarios where there is no "enclosing external API" with genuinely safe types, where this error is a legitimate type error that indicates a broken design.
There was a problem hiding this comment.
I'm not totally sure what to suggest though. I am having trouble describing the safe scenarios here.
It's more than just a matter of encapsulation. We could encapsulate an instance of an invariant type causing a type error, and it still be a legitimate error. We need to be confident the error would never occur (e.g. we'll never attempt to pass in a parameter that doesn't match the callback parameter type, and we'll never return a value that doesn't match the callback return type)
There was a problem hiding this comment.
Yes I'll clarify that sometimes we can't "re-impose types" and any won't be safe to use.
If it's possible to re-type either constraint to resolve an incompatible configuration without affecting downstream callers or introducing semantic inaccuracies, the type error does signal broken design and we shouldn't use any to suppress it.
Will push a new draft based on this.
View rendered version
Note
Low Risk
Low risk documentation-only change that clarifies when
anyis acceptable for callback parameters under bidirectional function-type constraints; no runtime or type-checking behavior is modified.Overview
Adds a new TypeScript guideline section that carves out a narrow exception for using parameter
anyin callbacks that sit in a bivariant position between two fixed, irresolvable function-type constraints.Includes examples distinguishing redesignable vs fixed constraints, guidance to annotate
eslint-disablecomments with the acceptance criteria, and an appendix-style derivation explaining whyunknown/neverfail under--strictFunctionTypes.Reviewed by Cursor Bugbot for commit 7c49096. Bugbot is set up for automated code reviews on this repo. Configure here.