Skip to content

[react] Properly type form-related events#74383

Merged
eps1lon merged 3 commits intoDefinitelyTyped:masterfrom
eps1lon:sebbie/01-22-_react_properly_type_form-related_events
Jan 27, 2026
Merged

[react] Properly type form-related events#74383
eps1lon merged 3 commits intoDefinitelyTyped:masterfrom
eps1lon:sebbie/01-22-_react_properly_type_form-related_events

Conversation

@eps1lon
Copy link
Copy Markdown
Collaborator

@eps1lon eps1lon commented Jan 22, 2026

This deprecates React.FormEvent which has no counterpart in the DOM and was equivalent to React.SyntheticEvent. Instead we're now adding the correct corresponding events to form-related event handlers (change, input, invalid, reset, submit).

As with any type change, this may cause type-checks to fail that were relying on bugs. We're only doing this change for the latest types (React 19) to reduce the blast radius. If the change is too disruptive, we may revert and defer to React 20.

This PR adds a second parameter to ChangeEvent specifying the target. Change events could have bubbled up so for most elements you should just use ChangeEvent<CurrentTarget>. Form-related elements like input already use ChangeEvent<CurrentTarget, HTMLInputElement>. In React 20, arbitrary onChange handlers will not get the narrowed target (see #69436 (comment)).

}
}

function formrelatedEventTests() {
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved from the React tests. It makes more sense here since React tests don't have access to the full lib/dom.d.ts.

Comment on lines -636 to -638
//
// The SyntheticEvent.target.value should be accessible for onChange
// --------------------------------------------------------------------------
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test wasn't actually testing it. Just that you can cast event.target up to a more specific EventTarget e.g. HTMLTextAreaElement. react-dom tests now assert in more detail when the target can be narrowed and not.

@eps1lon eps1lon force-pushed the sebbie/01-22-_react_properly_type_form-related_events branch from c63cd58 to fc3de51 Compare January 22, 2026 19:09
@eps1lon eps1lon force-pushed the sebbie/01-22-_react_properly_type_form-related_events branch from fc3de51 to a79247a Compare January 22, 2026 22:18
};

class SynchronousValidationForm
extends React.Component<ReduxFormProps<SynchronousValidationForm & HTMLFormElement>>
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This created a handleSubmit that assumes the onSubmit's target is an intersection of SynchronousValidationForm and HTMLFormElement. But the handleSubmit is passed to React's onSubmit which definitely won't provide that target. Looks like an oversight due to not properly typing onSubmit. Now we do so flushing out this seemingly invalid usage is expected.

@eps1lon eps1lon marked this pull request as ready for review January 23, 2026 10:57
@typescript-bot
Copy link
Copy Markdown
Contributor

typescript-bot commented Jan 23, 2026

@eps1lon Thank you for submitting this PR!

This is a live comment that I will keep updated.

3 packages in this PR

Code Reviews

Because this is a widely-used package, a DT maintainer will need to review it before it can be merged.

You can test the changes of this PR in the Playground.

Status

  • ✅ No merge conflicts
  • ✅ Continuous integration tests have passed
  • 🕐 A DT maintainer needs to approve changes that affect more than one package

Once every item on this list is checked, I'll ask you for permission to merge and publish the changes.


Diagnostic Information: What the bot saw about this PR
{
  "type": "info",
  "now": "-",
  "pr_number": 74383,
  "author": "eps1lon",
  "headCommitOid": "a79247a777886a820abc14d95d85c55a1df8cac1",
  "mergeBaseOid": "e42909429872fbf1865e12e389edba88f426f978",
  "lastPushDate": "2026-01-22T16:13:24.000Z",
  "lastActivityDate": "2026-01-23T10:57:17.000Z",
  "hasMergeConflict": false,
  "isFirstContribution": false,
  "tooManyFiles": false,
  "hugeChange": false,
  "popularityLevel": "Critical",
  "pkgInfo": [
    {
      "name": "react-dom",
      "kind": "edit",
      "files": [
        {
          "path": "types/react-dom/test/react-dom-tests.tsx",
          "kind": "test"
        }
      ],
      "owners": [
        "MartynasZilinskas",
        "theruther4d",
        "Jessidhia",
        "eps1lon"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Critical"
    },
    {
      "name": "react",
      "kind": "edit",
      "files": [
        {
          "path": "types/react/global.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/react/index.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/react/test/index.ts",
          "kind": "test"
        },
        {
          "path": "types/react/ts5.0/global.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/react/ts5.0/index.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/react/ts5.0/test/index.ts",
          "kind": "test"
        }
      ],
      "owners": [
        "johnnyreilly",
        "bbenezech",
        "pzavolinsky",
        "ericanderson",
        "DovydasNavickas",
        "theruther4d",
        "guilhermehubner",
        "ferdaber",
        "jrakotoharisoa",
        "pascaloliv",
        "hotell",
        "franklixuefei",
        "Jessidhia",
        "saranshkataria",
        "lukyth",
        "eps1lon",
        "zieka",
        "dancerphil",
        "dimitropoulos",
        "disjukr",
        "vhfmag",
        "priyanshurav",
        "Semigradsky",
        "mattpocock"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Critical"
    },
    {
      "name": "redux-form",
      "kind": "edit",
      "files": [
        {
          "path": "types/redux-form/v4/redux-form-tests.tsx",
          "kind": "test"
        },
        {
          "path": "types/redux-form/v5/redux-form-tests.tsx",
          "kind": "test"
        }
      ],
      "owners": [
        "aikoven",
        "LKay",
        "bancek",
        "huwmartin",
        "m-b-davis",
        "ethanresnick",
        "maddijoyce",
        "smifun",
        "mshaaban088",
        "esetnik",
        "mrsekut",
        "abemedia"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Popular"
    }
  ],
  "reviews": [],
  "mainBotCommentID": 3789674041,
  "ciResult": "pass"
}

@typescript-bot typescript-bot moved this from Needs Author Action to Needs Maintainer Review in Pull Request Status Board Jan 23, 2026
@typescript-bot
Copy link
Copy Markdown
Contributor

@eps1lon eps1lon merged commit 1bfb3a0 into DefinitelyTyped:master Jan 27, 2026
11 checks passed
@eps1lon eps1lon deleted the sebbie/01-22-_react_properly_type_form-related_events branch January 27, 2026 11:57
@jamesharrisatconnexian
Copy link
Copy Markdown

This broke our CI builds and I suspect 10 million other CI builds. I think we are all happy with this change but it was in fact marked as a patch version only and I don't see any changelog / migration docs?

@eps1lon
Copy link
Copy Markdown
Collaborator Author

eps1lon commented Jan 28, 2026

This broke our CI builds and I suspect 10 million other CI builds. I think we are all happy with this change but it was in fact marked as a patch version only and I don't see any changelog / migration docs?

Sorry to hear that. This is an unfortunate reality with type changes. Any change is a breaking change if existing code was relying on these bugs. I made a judgement call that this breakage is fairly small considering what I saw in internal apps.

If we'd hold off with every change until the next major, we'd rarely make progress. This one was a clear bug that should be fixed.

Do you have some examples that broken? This could help other readers resolve their issues faster.

@jamesharrisatconnexian
Copy link
Copy Markdown

This broke our CI builds and I suspect 10 million other CI builds. I think we are all happy with this change but it was in fact marked as a patch version only and I don't see any changelog / migration docs?

Sorry to hear that. This is an unfortunate reality with type changes. Any change is a breaking change if existing code was relying on these bugs. I made a judgement call that this breakage is fairly small considering what I saw in internal apps.

If we'd hold off with every change until the next major, we'd rarely make progress. This one was a clear bug that should be fixed.

Do you have some examples that broken? This could help other readers resolve their issues faster.

Thanks, I appreciate your work and I totally understand as a senior dev for over 20 yrs I do agree you just have to push it forward, however I would have expected some release docs around it, and a minor version increment. It just required refactoring our types to use the new ones but as of just 1 year ago we had been using the recommended types from official docs so its likely more of a docs out of date issue than anything on your part.

Thanks again for your work!

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants