-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Expose ThreeElements interface #2347
Conversation
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. |
I'm a fan of this. I experimented with similar in react-ogl, where I wanted to do away with hardcoded types (and instead iterate over the three/ogl namespace). There wasn't a way to distinguish what were DOM JSX types and three (they overlap a bit), so a separate interface (that would extend into JSX.IntrinsicElements) was useful to restrict instances to three/ogl properties. |
As an aside, is there a specific need to have all the hardwired types in |
There isn't a way to automate this in TypeScript without reflection. You'd need the class reference to draw
This isn't completely backward-compatible in the case of custom elements, since previous user-land usage for extend via JSX.IntrinsicElements won't be reflected in the new interface. Maybe this should be pointed to v9? |
@CodyJasonBennett sure, extending JSX.IntrinsicElements won't also extend ThreeElements, but I'm not sure that would be necessary to qualify as backward-compatible, because previous user-land usage doesn't have the concept of ThreeElements anyway, no? They could upgrade to this version and keep extending JSX.IntrinsicElements and they wouldn't know the difference. Or am I misunderstanding your point? |
A good +1 for the v9 major would be that this way we could also safely port drei & other echosystem libs with a hard dependency on v9 and change the extensions to target ThreeElements edit: Ops, double teamed with @AndrewPrifer 😆 |
My concern is that this is not strictly backward-compatible in the case of custom elements. Although this is a minor in R3F, it needs to be communicated by consuming libraries that a code change is required for custom elements to be respected via this new interface, semver from peer deps aside. This is something we'll want to note in R3F's release notes as |
I had meant to include this in 8.1 alongside #2339. Is this good to publish in 8.2? |
Is this going to be a breaking change for libs that look at |
No, but we'll want to make extending |
This PR directly exposes all the r3f-specific React element types, instead of directly augmenting
JSX.IntrinsicElements
.JSX.IntrinsicElements
still gets augmented, so it is fully backwards-compatible:This would be very useful for libraries that need to map over, or validate against r3f elements, like
@theatre/r3f
or@react-spring/three
. Currently the only option is to useJSX.IntrinsicElements
, which results in incorrect types that are way too broad and include other elements too, like those fromreact-dom
. Furthermore sinceJSX.IntrinsicElements
is huge, it can easily result in types that are either too complex for the type checker to handle, or too large for the compiler to serialize.An interesting thing about the way this is solved in this PR, is that augmenting
ThreeElements
in turn will also augmentJSX.IntrinsicElements
:The effect is that users would only have to augment a single interface, and it would automatically also work with all other libraries that depend on
ThreeElements
, while also exposing these elements in React.