-
Notifications
You must be signed in to change notification settings - Fork 46.9k
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
Bug: React 18 types broken since the type release a view hours ago #24304
Comments
@eps1lon I saw you merged the following PR DefinitelyTyped/DefinitelyTyped#56210 . Can you please provide feedback on the matter with PropsWithChildren from above please? |
Can we move this issue discussion to the DefinitelyTyped repository? That's where the React typings are maintained, and you'll probably see more people who are directly involved and can provide their thoughts on them. |
If I understand correctly, the issue you're referring to is https://solverfox.dev/writing/no-implicit-children/. It's not strictly related to React 18 per se, but it's a breaking change the maintainers of React typings have meant to do for a few years. I don't want to speak for them — but there'll probably never be a particularly “good time” to do it, and as it stands the types were wrong. So at some point there is a need to bite the bullet. It looks like there is an automated conversion available so maybe this is something you can try: https://github.com/eps1lon/types-react-codemod#implicit-children. |
@gaearon I will try the code-mod and provide feedback.
For others who may not be familiar with the definitely-typed repo, it would be great to get some orientation here. |
All the type-related breaking changes are explained in DefinitelyTyped/DefinitelyTyped#56210. Specifically implicit children have a lengthy explainer https://solverfox.dev/writing/no-implicit-children/. For migration of your own codebase you might want to take a look at https://github.com/eps1lon/types-react-codemod. That doesn't help with library types though. For errors in node_modules I'm currently working on an approach that restores as much of the React 17 types behavior as possible (see DefinitelyTyped/DefinitelyTyped#59751). I can't guarantee a timely release at the moment. I'm aware of the headaches this release causes and hope that you can understand why we made these changes. Some of these changes have been scheduled for years now and we already skipped the v17 release for that. |
quick and dirty, install on scripts,
on resolutions
|
I totally understand that breaking changes are needed sometimes. I only want to suggest that the next time you add a deprecation warning with a I would have stopped using this syntax a long time ago if my editor started warning me this was deprecated syntax. |
Can you clarify which syntax you're referring to? |
Specifically I also noticed a few dependencies breaking, React Helmet (recent version) and theme-ui (older version) among others. I already reverted the upgrade so I don't have more details unfortunately. |
I see. I'm not sure |
I agree that the typing for this seems tricky. The missing deprecation message is unfortunate and seems to be a weakness of Typescript. It happens when you destructure children in the arguments. If you use it in the function body it does show up:
The user experience of getting deprecation warning in advance of things changing is nice though - if possible to achieve. After a recent minor Mobx upgrade I started seeing these in the logs when running in development mode and when running tests:
It's a nice heads up to get, letting me know I should start updating the code in advance of thing actually breaking. |
if you use yarn, just use the resolutions, no need for npm-force-resolutions |
It works very well, thanks |
This breaks everything! 😭 How long are you going to release this outdated |
Please file an issue in those packages. I’m not sure I understand why a library would need to include React types in its dependencies at all. |
@testing-library/react does this. Here's the Issue (links to PR) describing why they had to do that testing-library/react-testing-library#1000 |
Interesting. This does seem like a potential pitfall when new versions come out. Shouldn't it be a peerDependency? Maybe @eps1lon knows more about how this is supposed to work. |
@gaearon This is sorta necessary for libraries that ship TS types. TS compiles app source, which refers to LibA types, which point to React types. So, either you explicitly say "LibA depends on I was actually just debating this with @Andarist for React-Redux v8, and what we settled on was an optional peer dep: "peerDependencies": {
"react": "^18.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}, so we're assuming that the user will already have those types installed if they plan on using React-Redux with TS. But, given that this is a relatively newer thing for |
Agreed that an optional peer dependency is the best option at the moment for library maintainers. That way users are more in control of which version is installed. However |
the odd thing about the types is that they are global somehow. I have a React15 project with a react 17 sub project in a folder inside it. The react18 types from the sub folder somehow cause errors in the main project 🤔 |
…owngrade `@types/react` and `@types/react-dom` back to `v17.x.x` because of the breaking changes in version 18 that could not be fixed until either material-ui is upgraded to v5 or this PR (DefinitelyTyped/DefinitelyTyped#59751) is merged Note this codemod (https://github.com/eps1lon/types-react-codemod) would not help because the errors are caused by library (see this facebook/react#24304 (comment) for the details) References: 1. https://stackoverflow.com/questions/71810438/compilation-issue-with-react-typescript-and-material-ui-4 2. DefinitelyTyped/DefinitelyTyped#56210 (comment) 3. facebook/react#24304 (comment) 4. https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/ 5. facebook/react#24304 (comment)
I got more errors after applying this method |
npm 6Edit the package-lock.json file to remove the "*" in the types to the version you are using then use "npm ci" which will use your package-lock file to do the install. If you add other dependencies you may just need to update the lock file again, but you can have a stable build. |
Still not fixed. |
There’s nothing to be fixed here. Please read the discussion. I’ll close this issue to make it clearer. |
I was able to resolve this issue with a package.json change: "optionalDependencies": { |
We had the same problem today. I have forced to use version 17 of the package with:
and it stopped resolving to version 18, so it is now working again. Maybe it will help you |
@xxxxue This is what yarn |
(just for reference) in a typical component you will have a mix of "native" react elements and custom react components, like: import React from 'react';
import type { ReactNode } from 'react';
function Comp({children}: {children?: ReactNode}) {
return <div>
{children}
</div>
} The problem actually comes because the type of
So while This almost guarantees that any project using |
ok I think I found the breaking change: // in @types/react v17:
type ReactFragment = {} | ReactNodeArray;
// in @types/react v18:
type ReactFragment = Iterable<ReactNode>; which is used in
I'm trying to see if I create a compatibility layer, like I wish JSX was not global and so would not effect the project still using @types/react v17 😭 |
I managed a workaround using typescript's {
"compilerOptions": {
"paths": {
"react": [ "./node_modules/@types/react" ]
}
}
} This tells Typescript to always resolve "react" from this location. It works better than resolutions because it forces typescript to use this single instance, solving my complicated use-case with two linked workspaces. Looking deeper into the breaking changes, and fixing errors as I upgrade to v18, I see they are really important. Since there are almost no breaking changes in v18, it seems the only way out is forward. It will be tricky not to break my consumers. I do wish that |
Candidate for worst design choice of the year. Nothing better than being locked into this ecosystem. Now every What possible benefit is received in exchange for all of this? |
The workarounds in #24304 (comment) address this. It sucks that there need to be workarounds, but ultimately we need to be able to make breaking changes to types in major versions. If you dislike the experience, the TypeScript and/or DefinitelyTyped tooling repositories are the right place to complain, since the practice of using
The major benefit is that the compiler no longer lets objects through (which crash at runtime). The issue is described in https://fettblog.eu/react-types-for-children-are-broken/. |
I want to reiterate that using TypeScript is a choice. You don't have to use React with TypeScript. If you choose to use React with TypeScript, the problems with the TypeScript ecosystem will affect you. The pervasiveness of the |
Hey all, I want to provide some context from the TypeScript/DT side. First, the current state of the world doesn't have an immediate fix that makes everything good and easy again. I don't think we can feasibly do anything without breaking other existing users. I'm sorry that things have ended up rocky here. If you're dealing with duplicate installations of Switching existing packages to move It may be worth revisiting Otherwise this thread is fairly long, and it doesn't seem to be getting any more productive. It may be worth locking the thread so users can easily see the workarounds I've mentioned above. |
well, we should then complain to "@types/react" ? :) |
No because the problem isn’t with the React typings. It’s with the way typing dependencies are expressed in the TS ecosystem. You could argue that the problem is with every package that specifies version The longer-term solution to this is being discussed in microsoft/DefinitelyTyped-tools#433. The short-term workarounds are described in #24304 (comment). This thread is starting to go in circles. I’m afraid there isn’t anything actionable on the React side here so I’m going to lock this thread as resolved. If you believe there’s something actionable for React, please file a new issue and let us know how we can help. Thank you! |
Edit: If you have issues but you did NOT upgrade to 18, or if you upgraded but get confusing errors from dependencies, the problem is likely that some library (incorrectly) specifies
@types/react
as a dependency with version*
rather than an optional peer dependency. Find which library it is and file an issue for it. See #24304 (comment) for diagnostics and common workarounds.A few hours ago, a major version of React types for Typescript was released.
I have tried to test this right away to see if there are any changes that require adaptation in my own projects.
Due to a very large number of users using React's type library (we use fundamental types like React.FC by the hundreds in our own projects), it's reasonable to question whether there's been a small mistake here.
Specifically, the following type declaration still exists in the 18 release.
However, this is no longer used in the library, at least not when looking at the diff
DefinitelyTyped/DefinitelyTyped@55dc209
A quick search on Github yields millions of hits that use the type alias React.FC to the actual type React.FunctionalComponent.
Before
Now
I think matching very, very many places in a single project doesn't seem to do justice to the change made; always the property children?: ReactNode to be redefined is definitely too much effort.
Positions at which PropsWithChildren were used before
Thx!
The text was updated successfully, but these errors were encountered: