This suggestion is motivated by react-three-renderer, which creates a custom renderer for React around the THREE library, and specifically this issue: https://github.com/toxicFork/react-three-renderer/issues/127.
This library was not written with Typescript in mind, and uses lowercased JSX elements for children of its main React3 component. For example:
<React3 width={800} height={400} clearColor={0xf0fff0} mainCamera="camera">
<scene>
<perspectiveCamera fov={75} aspect={800/400} near={0.001} far={1000} name="camera" ref="camera"
position={new THREE.Vector3(0,0,5)} rotation={new THREE.Euler()}/>
<ambientLight color={0x505050}/>
<line>
<geometry vertices={vertices}/>
</line>
</scene>
</React3>
While it's possible to avoid compiler warnings by modifying JSX.IntrinsicElements this causes issues where there are conflicts, for example line in the above example which is also an SVG element. Also, within the React3 component it is not sensible/valid to put normal HTML elements, so it would be good to exclude these.
I am following https://github.com/Microsoft/TypeScript/issues/14729 and https://github.com/Microsoft/TypeScript/issues/13618 which seem somewhat related, but don't appear to address this specific issue.
In summary, it should be possible to indicate somehow that a component uses a different set of intrinsic elements, other than JSX.IntrinsicElements.
+1. React Fiber should be released soon and many custom renderers will be appearing.
Hi @RyanCavanaugh you tagged with Awaiting More Feedback a while ago. Are you wanting feedback from me as the person who raised the issue or from the typescript team? Thanks!
as the person who raised the issue or from the typescript team?
It means it is awaiting more feedback from the community as a whole. It means that it isn't obvious to the core team that it is worth expending effort on this suggestion unless there is wider support from the community.
(I was going to point you at the label list but it appears this one isn't listed)
This means we'd like to hear from more people who would be helped by this feature, understand their use cases, and possibly contrast with other proposals that might solve the problem in a simpler way (or solve many other problems at once).
If this feature looks like a good fit for you, please use the :+1: reaction on the original post. Comments outlining different scenarios that would be benefited from the feature are also welcomed.
Hi :)
I'm the author of react-three-renderer and would like to contribute to TypeScript's support for custom renderers if possible :)
Here are a few kinds of renderers that some initial research has shown:
To go into more detail with react-three-renderer, any element that is rendered within a React3 component would be handled by react-three-renderer instead of react-dom.
To extend the above example:
function testRender() {
return <div>
Check out this three dimensional thing:
<div>
<React3 {/* diving into react-three-renderer domain now */ ...{}}>
<webGLRenderer width={800} height={600} antialias>
<scene>
<mesh>
<boxGeometry width={10} height={10} depth={10} />
<meshBasicMaterial
color={"FF0000"}
/>
</mesh>
</scene>
</webGLRenderer>
</React3>
</div>
</div>;
}
By looking at this I can think of various potential solutions (assuming no technical limitations):
React3 component could somehow have a tag to specify "which type of elements it may contain as children"x-search component would be accepting only children that are x-query and x-engine, while another x-wrapper component would be accepting normal dom nodesreact3 web component to have best of both worlds... :D)import {Ref} from "react";
declare namespace ReactThreeRenderer {
interface IBoxGeometryProps {
width: number;
height: number;
depth: number;
}
interface IReactThreeRendererElement<T> {
key?: string;
ref?: Ref<T>;
}
interface IntrinsicElements {
boxGeometry: IReactThreeRendererElement<THREE.BoxGeometry> & IBoxGeometryProps;
meshBasicMaterial: IReactThreeRendererElement<THREE.MeshBasicMaterial> & THREE.MaterialParameters;
}
}
/// <jsx-intrinsic-elements using="ReactThreeRenderer.IntrinsicElements"/>
function testRender() {
return <scene>
<mesh>
<boxGeometry width={10} height={10} depth={10} />
<meshBasicMaterial
color={"FF0000"}
/>
</mesh>
</scene>;
}
mesh element can contain only geometry and material types, e.g.:boxGeometry, sphereGeometry and so on, meshBasicMaterial, meshLambertMaterial and so onI hope it helps!
Firtina.
I think this could be handled by checking the children of intrinsic elements the same as non-intrinsic elements.
I've run into a similar case where I'm leveraging JSX to do declarative xml building. I have certain constraints on child-parent relationships that are great for non-intrinsic elements, but don't appear to be type-checked for intrinsic elements.
I also vote for this feature. The use case I would image is following:
in angular or vue templates we are able to use components defined and registered in top-level module, so it would be nice to use these components without importing them explicitly as modules. It could look something like
import { myModule } from '../myModule'
myModule.component({
name: 'foo',
render: () => (
<sui-button size="large">Submit</sui-button>
)
})
with render function typed somehow that it's allow to use custom JSX.IntrinsicElements inside of it
interface Component {
name: string,
render: JSX.RenderFunction<{
"sui-button": {
size?: "large" | "small"
},
"other-component": {
someProp?: number
}
}>
}
I guess it can possibly allow supporting directives in JSX as well
Most helpful comment
Hi :)
I'm the author of react-three-renderer and would like to contribute to TypeScript's support for custom renderers if possible :)
Here are a few kinds of renderers that some initial research has shown:
To go into more detail with react-three-renderer, any element that is rendered within a
React3component would be handled by react-three-renderer instead of react-dom.To extend the above example:
By looking at this I can think of various potential solutions (assuming no technical limitations):
React3component could somehow have a tag to specify "which type of elements it may contain as children"x-searchcomponent would be accepting only children that arex-queryandx-engine, while anotherx-wrappercomponent would be accepting normal dom nodesreact3web component to have best of both worlds... :D)meshelement can contain onlygeometryandmaterialtypes, e.g.:boxGeometry,sphereGeometryand so on,meshBasicMaterial,meshLambertMaterialand so onI hope it helps!
Firtina.