-
Notifications
You must be signed in to change notification settings - Fork 30.5k
[react] Types for React 19 #69022
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
[react] Types for React 19 #69022
+35,807
−4,935
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6f5e24f to
bd58fbf
Compare
47920ab to
51e726f
Compare
This was referenced Mar 26, 2024
Not meant to be used directly. Omitting all exports so that they don't appear in IDE autocomplete.
Contributor
|
@DiegoAndai, @Eyas, @zeorin, @remcohaszing, @karlhorky, @ChristianMurphy Thank you for reviewing this PR! The author has pushed new commits since your last review. Could you take another look and submit a fresh review? |
Contributor
|
Amazing, thanks @eps1lon and everyone else who contributed here on the long journey to React 19 stable! 🎉 🚀 |
30 tasks
Philipp91
added a commit
to Philipp91/recharts
that referenced
this pull request
Dec 7, 2024
For React v19 type compatibility, see DefinitelyTyped/DefinitelyTyped#69022.
This was referenced Dec 7, 2024
4 tasks
Robot-Inventor
added a commit
to Robot-Inventor/mdui
that referenced
this pull request
Feb 26, 2025
The `JSX` namespace in React was deprecated in [DefinitelyTyped PR #64464](DefinitelyTyped/DefinitelyTyped#64464) and removed in [DefinitelyTyped PR #69022](DefinitelyTyped/DefinitelyTyped#69022). Instead, `React.JSX` should be used.
zdhxiong
pushed a commit
to zdhxiong/mdui
that referenced
this pull request
Feb 27, 2025
The `JSX` namespace in React was deprecated in [DefinitelyTyped PR #64464](DefinitelyTyped/DefinitelyTyped#64464) and removed in [DefinitelyTyped PR #69022](DefinitelyTyped/DefinitelyTyped#69022). Instead, `React.JSX` should be used.
This was referenced Aug 28, 2025
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
Check Config
Changes a module config files
Critical package
Edits Infrastructure
Edits multiple packages
Huge Change
pkg: [email protected]
Discussions related to the release of React 19.0
Too Many Owners
Unreviewed
No one showed up to review this PR, so it'll be reviewed by a DT maintainer.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
19.0.0-rc.1has been released and if nothing urgent comes up, will be the final React 19 release soon.Please do not merge this just yet.
Changelog
Table of Contents
useReducerReactElementpropTypesanddefaultPropsstaticsIn recent years, the API surface of
@types/reacthas gotten larger than we'd like.This makes working with React and TypeScript unnecessarily tricky.
So, we're taking this opportunity to make some small breaking changes to our types, deprecating some and removing others.
We've wanted to make the migration easier - most can be automated with codemods.
Check out the migration guide below for more information.
The runtime changes are far more important since they directly affect the end user of your application.
They'll be detailed in React's release notes.
Migrating
While we have included some breaking changes, most of them can be resolved with codemods to keep manual work to a minimum.
Quick Explanation
Full Explanation
Almost all of the
@types/*packages are already compatible with React 19 types unless they specifically rely on React 18. Therefore it is advised to upgrade all React-related@types/*packages first.Apply the
preset-19codemod fromtypes-react-codemodin its default configuration vianpx types-react-codemod@latest preset-19 ./path-to-your-react-ts-files.In our experience, this covers most breaking changes.
The largest block of remaining type issues relate to props of React elements now defaulting to
unknowninstead ofany.If you're focus is on migration instead of soundness, you can use the
react-element-default-any-propsto resolve a large portion of the breaking changes related toReactElement.However, the codemod can't cover every pattern.
You probably have to manually adjust the lines relying on
anyinelement.propseither by additional runtime checking or manual casts toany.You can check out the example migrations done on libraries e.g. MUI or apps e.g. Bluesky to get an idea of the possible patterns.
Breaking changes
This section focuses on breaking changes for the React types.
Some types have been removed, some type parameters have been changed, and
useRefhas been simplified.Removed Types
We've removed these types from
@types/react.Some of them have been moved to more relevant packages, like
Validatormoving toPropTypes.Others are no longer needed to describe React's behavior.
Removing them means one less thing to learn.
Codemoddable
ReactChilddeprecated-react-childReact.ReactElement | number | stringReactFragmentdeprecated-react-fragmentIterable<React.ReactNode>ReactNodeArraydeprecated-react-node-arrayReadonlyArray<React.ReactNode>ReactTextdeprecated-react-textnumber | stringRequireabledeprecated-prop-types-typesRequireablefromprop-typesValidationMapdeprecated-prop-types-typesValidationMapfromprop-typesValidatordeprecated-prop-types-typesValidatorfromprop-typesVoidFunctionComponentdeprecated-void-function-componentFunctionComponentVFCdeprecated-void-function-componentFCWeakValidationMapdeprecated-prop-types-typesWeakValidationMapfromprop-typesNot Codemoddable
During our example migrations, these types were not used at all.
So, we felt comfortable leaving them off our codemod list.
If you feel a codemod is missing, it can be tracked in the list of missing React 19 codemods.
ClassicComponentClassClassicComponentClassfromcreate-react-classClassicComponentClassicComponentfromcreate-react-classClassicElement<Props>ClassicElement<Props, InstanceType<T>>fromcreate-react-classComponentSpecComponentSpecfrom thecreate-react-classpackageMixinMixinfrom thecreate-react-classpackageReactChildrentypeof React.ChildrenReactHTMLReactHTMLfromreact-dom-factoriesor, if you usedkeyof ReactHTML, useHTMLElementTypeinsteadReactSVGReactSVGfromreact-dom-factoriesor, if you usedkeyof ReactSVG, useSVGElementTypeinsteadSFCFactoryJSX Namespace
A long-time request is to remove the global
JSXnamespace from our types in favor ofReact.JSX.This helps prevent pollution of global types which prevents conflicts between different UI libraries that leverage JSX.
This change is codemoddable with
scoped-jsx.This means that if you're doing any module augmentation of
JSX:You'll now need to wrap it in
declare module "....":The exact module specifier depends on the JSX runtime you specified in the
compilerOptionsof yourtsconfig.json.For
"jsx": "react-jsx"it would bereact/jsx-runtime.For
"jsx": "react-jsxdev"it would bereact/jsx-dev-runtime.For
"jsx": "react"and"jsx": "preserve"it would bereact.Changes to Type Parameters
useReduceruseReducernow has improved type inference thanks to @mfp22.However, this required a breaking change where we don't accept the full reducer type as a type parameter but instead either want none (and rely on contextual typing) or want both the state and action type.
The new best practice is not to pass type arguments to
useReducer.However, this may not work in edge cases where you can explicitly type the state and action, by passing in the
Actionin a tuple:If you define the reducer inline, we encourage to annotate the function parameters instead:
This, of course, is also what you'd also have to do if you move the reducer outside of the
useReducercall:ReactElementThe
propsof React elements now default tounknowninstead ofanyif the element is typed asReactElement. This does not affect you if you pass a type argument toReactElement:But if you relied on the default, you now have to handle
unknown:If you rely on this behavior, use the
react-element-default-any-propscodemod.You should only need it if you have a lot of legacy code relying on unsound access of element props.
Element introspection only exists as an escape hatch and you should make it explicit that your props access is unsound via an explicit
any.Component types
Due to the removal of legacy context, forward ref render functions (e.g.
(props: P, ref: Ref<T>) => ReactNode) will now be rejected by TypeScript if used as a component type.This was almost always a bug that needed fixing by wrapping the render function in
forwardRefor removing the secondrefparameter.Ref cleanup
React 19 allows returning a "cleanup function" from callback refs.
This means returning anything else will now be rejected by TypeScript.
The fix is usually to stop using implicit returns e.g.
The original code returned the instance of the
HTMLDivElementand TypeScript wouldn't know if this was supposed to be a cleanup function or if you didn't want to return a cleanup function.You can codemod this pattern with
no-implicit-ref-callback-returnpropTypesanddefaultPropsstaticspropTypesare now ignored by React.However, to ease migration, we just type
propTypesasanyto ease migration in case these components are a bridge between typed and untyped components.If we'd remove
propTypesentirely, a lot of assignments would cause TypeScript issues.The same does not apply to
defaultPropson function components since not rejecting them during type-checking would cause actual issues at runtime.Please check out the changelog entry for the removal of
defaultPropsto learn how to migrate off ofdefaultProps.Ref changes
A long-time complaint of how TypeScript and React work has been
useRef.We've changed the types so that
useRefnow requires an argument.This significantly simplifies its type signature. It'll now behave more like
createContext.This now also means that all refs are mutable.
You'll no longer hit the issue where you can't mutate a ref because you initialised it with
null:MutableRefis now deprecated in favor of a singleRefObjecttype whichuseRefwill always return:We still have a convenience overload for
useRef<T>(null)that automatically returnsRefObject<T | null>.To ease migration due to the required argument for
useRef, we also added a convenience overload foruseRef(undefined)that automatically returnsRefObject<T | undefined>.Check out [RFC] Make all refs mutable for prior discussions about this change.
Codemod
When you apply the
useRef-required-initialcodemod (part ofpreset-19), alluseRef()calls will be converted touseRef(undefined).Repo stuff, not the changelog
Thanks to @mattpocock for writing the changelog!
Closed issues
Closes #64451
Closes #64896
Closes #64772
Closes #64412
Closes #64920
Reviewer notes
Packages that pin
@types/react@^18either need more work to get compatible or depend on a library that's not hosted in this repo. The other libraries are other compatible or have been made compatible in this PR as a best effort.For changes to React runtime APIs, please file them as issues to facebook/react instead. Keep the discussion focused on types.
For changelog review, please use eps1lon#35
CI failure related to "React 19 not found on NPM" is expected. All the other failures need to be gone. I'll extracted as many required changes to other packages as possible to earlier PRs.
Maintainer notes
Before merge:
Create React 18 fork with https://github.com/eps1lon/react-types-tools/blob/main/createReact18TypesFork.sh
Backport changes to ts5.0 fork with