Skip to content

fix(core)!: type per-key event-handler arguments for useSpring/useTransition#2551

Open
joshuaellis wants to merge 1 commit into
nextfrom
fix/per-key-handler-types
Open

fix(core)!: type per-key event-handler arguments for useSpring/useTransition#2551
joshuaellis wants to merge 1 commit into
nextfrom
fix/per-key-handler-types

Conversation

@joshuaellis

Copy link
Copy Markdown
Member

Summary

Per-key event-handler arguments now infer their type from the animated value instead of leaking any. In useSpring({ x: 0, onChange: { x: result => result.value } }), result.value is now number; the same holds for onStart/onChange/onRest/onPause/onResume (and onProps) across useSpring and useTransition, which also tightens from unknown to the key's value type. This removes a recurring source of unchecked handler arguments (#2183).

Why it leaked

The handler callback sits inside the same object literal that the hook's Props generic is inferred from, so TypeScript can't contextually type it from the still-inferring generic and falls back to any. The new EventfulProps helper sources the handler keys from the resolved props via NoInfer, so the state resolves first and the callbacks receive the key's value type. Typo detection is preserved as an inference-neutral layer.

Breaking change

To make the inference work, the props parameter no longer accepts the loose UseSpringProps/UseTransitionProps escape-hatch union member. Object literals and pre-typed props are unaffected; loosely-typed or dynamically-built props objects, and Parameters<typeof useSpring> extraction, are now checked more strictly.

Out of scope

useSprings is unchanged. Its props are an array, which TypeScript collapses to a single inferred type via best-common-type — fundamentally incompatible with the per-element phasing this fix relies on. The lazy () => props forms are likewise unaffected. Both are documented inline; annotate handler arguments there.

Part of #2541.

…nsition

Per-key handlers now infer result.value from the animated value instead of any. Breaking: props are stricter (the loose UseSpringProps escape-hatch arm is gone). useSprings is unchanged (array-inference limitation). Part of #2541.
@changeset-bot

changeset-bot Bot commented Jun 24, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 364f733

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 9 packages
Name Type
@react-spring/core Major
@react-spring/three Major
@react-spring/web Major
@react-spring/parallax Major
@react-spring/animated Major
@react-spring/mock-raf Major
@react-spring/rafz Major
@react-spring/shared Major
@react-spring/types Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant