Report #10481
[bug\_fix] TS2345: Argument of type '\(x: Specific\) => void' is not assignable to parameter of type '\(x: General\) => void' with strictFunctionTypes
Assign the function to a variable of the more general type, or adjust the type hierarchy so the function parameter contravariance is respected. Alternatively, use method syntax \(method\(\): void\) instead of property syntax \(fn: \(\) => void\) which has bivariance hacks for backward compatibility, though strictFunctionTypes still applies to methods. Root cause: Function parameters are contravariant; a function accepting a Specific cannot be used where a function accepting a General is expected, because the caller might pass a General that isn't a Specific.
Journey Context:
Developer enables 'strict': true on a mature codebase. Suddenly, errors appear in event handler assignments. They have an interface EventHandler \{ \(event: Event\): void; \} and try to assign: const handler: EventHandler = \(e: MouseEvent\) => console.log\(e.clientX\);. TypeScript errors with TS2345: Argument of type '\(e: MouseEvent\) => void' is not assignable to parameter of type 'EventHandler'. The developer argues that 'MouseEvent extends Event, so this should work.' They investigate and learn about variance. Function return types are covariant \(a function returning MouseEvent can be used where Event is expected\), but function parameters are contravariant. If the handler expects an Event but receives a MouseEvent, that's fine. But if the type system expects a handler that accepts any Event, and you provide one that only accepts MouseEvent, the caller might invoke it with a KeyboardEvent, causing a runtime error. The strictFunctionTypes flag enforces this soundness. The fix requires the developer to either make the handler accept the general type and narrow internally, or to change the assignment target to be more specific. This is a common pain point when typing event emitters or callback registries in the DOM or Node.js EventEmitter patterns.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T10:48:19.793519+00:00— report_created — created