-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
TypeScript #11
Comments
Sure, that would be awesome! Would you like to work on that? I am more than willing to share this lib, put it on a neutral org at some point and give out access rights. No point in just one person dealing with it. Just need to get the initial foundation right. (@bl4ckm0r3) TS is something i wouldn't be able to do myself (still need to learn it 😓) |
I think it's a good idea! |
Started yesterday, just making it compile through babel now: https://github.com/ksjogo/react-three-fiber/tree/typescript Yes, there are types for three as well: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/three |
Is the goal to write the library in TypeScript, or to consume it from TypeScript? @ksjogo's branch is doing the first. Though I'm more interested in the second. It's not clear initially how to write my own type definitions for the library. The Three-related components need to be added to in JSX.IntrinsicAttributes, though I haven't figured out how to do that. |
I would be fine with both, though with react-spring contributed types were always lagging behind and when i made changes to the lib i didn't know how to update them (b/c i don't know tS). if the lib itself is TS i have to make do and i think it's a better experience for you all. |
I've created a react.d.ts file and extended the
I did this just so that it works on my typescript project. |
Is anyone working on typescript defs atm or plans to do it? |
Yes, #59 |
To make the types for the JSX elements automatically generated following what |
In the meantime, while we don't have that Typescript feature, we can use a work-around to consume react-three-fiber from Typescript. Just replace this code: function Thing({ vertices, color }) {
return (
<group ref={ref => console.log('we have access to the instance')}>
<line>
<geometry
attach="geometry"
vertices={vertices.map(v => new THREE.Vector3(...v))}
onUpdate={self => (self.verticesNeedUpdate = true)}
/>
<lineBasicMaterial attach="material" color="black" />
</line>
<mesh
onClick={e => console.log('click')}
onPointerOver={e => console.log('hover')}
onPointerOut={e => console.log('unhover')}>
<octahedronGeometry attach="geometry" />
<meshBasicMaterial attach="material" color="peachpuff" opacity={0.5} transparent />
</mesh>
</group>
)
} by that code const e = React.createElement;
function Thing({ vertices }: { vertices: [number, number, number][] }) {
return (
e('group', { ref: ref => console.log('we have access to the instance') },
e('line', null,
e('geometry', {
attach: 'geometry',
vertices: vertices.map(v => new THREE.Vector3(...v)),
onUpdate: (self: any) => (self.verticesNeedUpdate = true),
}),
e('lineBasicMaterial', { attach: 'material', color: 'black' }),
),
e('mesh',
{
onClick: (e: any) => console.log('click'),
onPointerOver: (e: any) => console.log('hover'),
onPointerOut: (e: any) => console.log('unhover')
},
e('octahedronGeometry', { attach: 'geometry' }),
e('meshBasicMaterial', { attach: 'material', color: 'peachpuff', opacity: 0.5, transparent: true })
)
)
);
} This way, we can use react-three-fiber until it becomes fully typed. By the way: I don't understand why this great framework works at all! How does |
@mattes3 check out https://github.com/facebook/react/tree/master/packages/react-reconciler react-dom is the reconciler, it contains the native elements (div, span, ..), knowledge units and so on, and of course the dom api (append, remove,...). likewise, this config: https://github.com/drcmda/react-three-fiber/blob/master/src/reconciler.tsx#L270-L342 teaches react about threejs. if you fill out these names you can use react for anything you want. |
@drcmda Ah, that explains it! Thanks, Paul! |
Is react-three-fiber currently usable in a Typescript project? I see that this issue is still open, but the above merge request has been merged and (presumably) released. I ask because TS is reporting various type errors in react-three-fiber/types which I can't resolve in my project which I'm attempting to convert from React 15/react-three-renderer to React 16/react-three-fiber. I wanted to check if this is expected to work currently, in which case I'd keep trying and perhaps open a new issue if I can't solve it, or if it's still a work in progress, in which case I should report my problems here. For the record, I'm getting an error that
I'm also getting errors about the
|
it's ongoing, but def needs help and contributions. there are workarounds for line and audio, we're using line_ for instance. but ultimately this error is with TS which treats dom types wrongly. |
Hello, I'm a little late to the party, but is there anything you need help with on this? As far as I understood the task is to add the proper elements to |
@bali182 i think the types are all available for threejs - but the lib is in a rough spot generally when it comes to TS atm. It wouldn't compile and there's some spots left that are still "any". if you see something that's fixable, sure, go ahead, would love to receive your pr. |
Hello, I'm having an issue with some of the typings for the JSX elements, that I think I fixed, but would like your input before submitting a PR.
After investigation Anyway, here is the fix that worked for me : I changed
(ie, I use typescript built-in Then, the args of my Obviously the Let me know if that sounds correct to you, and I'll submit a PR. Cheers |
want to start out by thanking you for all your hard work here! this is an amazing library, and its exciting to get in on this with so much moving. :) i'm getting the same errors with audio, but am more concerned about this clash of the JSX DOM names, what happens if i want to use an HTML DOM element in a project as well? It feels like this is something I should be able to do and the clash is a bit confusing. |
the only elements i am aware of that cause problems are line, and audio. and the error is with typescript. there is nothing we can do other than hoping microsoft will fix it. jsx is a cross platform standard, it has no relation whatsoever with the dom. that they assume dom elements in the jsx intrinsic types is really weird. there are couple of issues open in the ts issue tracker requesting a better solution. maybe if someone knew how to phrase that we could try to bring it to the attention of the react team. but as i said, in the meantime use line_/audio_ and it's fine. you can of course mix dom elements and three elements inside of their respective reconcilers. import { ReactThreeFiber } from 'react-three-fiber/types/three'
declare global {
// tslint:disable-next-line: no-namespace
namespace JSX {
// tslint:disable-next-line: interface-name
interface IntrinsicElements {
line_: ReactThreeFiber.Object3DNode<THREE.Line>
audio_: ReactThreeFiber.Object3DNode<THREE.Audio>
}
}
} |
alright then. thanks for explaining, and appreciate the code example! looking at submitting a PR of updates to the types in the next few days, will check and see what people are doing. |
made some progress today, the lib finally runs through TS without errors: #168 there are a couple of any's left in the reconciler but i doubt they can be fixed since it can basically accept any object given to it via extend. |
wow! this is fantastic. going to help so much with my project i'm working on. thanks for taking this on. :) |
@drcmda ah awesome work! Is this in the |
hope tomorrow, i'll do some more testing in case i broke something. |
So when the next PR is merged, this will work automatically without extra imports? |
Yes, the extra import should not be needed any more after #170 |
With dependencies of @drcmda - when you said that react-three-fiber@^2.3.0 "runs through TS without errors", how did you resolve this type conflict? I'm presumably doing something wrong... |
@RobRendell please, take a look at #172 |
@RobRendell I add configuration to tsconfig.json, generally we don't need to verify node-module,This works fine. |
@ksjogo it took some time, but react-three-fiber v4 should work with TypeScript pretty well :) |
Hello! |
yes, they're not part of three/types import { ReactThreeFiber } from 'react-three-fiber'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
declare global {
namespace JSX {
interface IntrinsicElements {
orbitControls: ReactThreeFiber.Object3DNode<OrbitControls, typeof OrbitControls>
}
}
} |
Is the array short hand syntax supported yet? I have the following line in my code: <polarGridHelper args={[ 200, 16, 16, 64, 0x333333, 0x333333 ]} rotation={[Math.PI / 2, 0 ,0]} /> and typescript reports that I think problem is that the corresponding codelines are only covered by the properties type from (inherited) Object3D and need to be something like Or am I doing it wrong? |
Ah, I digged a little bit deeper. I think the Is this file generated? I would do a PR. I would also suggest to improve definitions of Euler, Vector3, etc. with Properties utility Type, like mentioned above. |
hey @micha149, three-types.ts is handwritten. The only thing that is generated is components/generated.ts
Edit: I'll just note a workaround here. As we wait for micha149's PR 😉, import { PolarGridHelper } from 'react-three-fiber/components';
// React.FC<ReactThreeFiber.Object3DNode<PolarGridHelper, typeof PolarGridHelper>>
const _ = <PolarGridHelper />; Proof by CodeSandbox: https://codesandbox.io/s/modest-flower-k63fx?fontsize=14&hidenavigation=1&theme=dark |
@hasparus can the typedef file be autogenerated perhaps? |
I kinda assumed that three-types.ts is more correct than my codegened types, because it's older 😄 We're generating this big stupid file (generated.ts) which has the strings we're interested in asserted as types of components to provide TS support. If we'd remove Our And ince interface IntrinsicElements {
primitive: { object: any, [properties: string]: any }
new: { object: any, args: any[], [properties: string]: any }
} ^btw this is a nice argument for lying about the types like React Native. IntrinsicElements is just so much underpowered compared to I have two worries/questions I'd have to investigate.
Note: The last two lines of console.log(execSync(`yarn prettier --write ${outPath}`, { encoding: 'utf-8', stdio: 'pipe' }))
console.log(execSync(`./node_modules/.bin/eslint --fix ${outPath}`, { encoding: 'utf-8', stdio: 'pipe' })) |
A complete generation can become difficult, if not impossible. For example the situation where you can pass an array for |
I suppose we’d only try generating IntrinsicElements. |
So disappointing that this library doesn't work with typescript: Property '0' is missing in type 'ReactText[]' but required in type '[number, (number | undefined)?, (number | undefined)?]'. |
Hey @ralexand56, does this error appear in one of the examples, in library code or in your code? It means that an array can't be empty and can't be longer than 3 elements. The thing that's now glowing red also requires numbers, and Would you like to share a CodeSandbox or a link to your repo in Discussions? You can tag me there. I might be able to help you. |
@ralexand56 The good news is that it does work with Typescript - I managed to convert my Typescript react-three-renderer project to react-three-fiber after they released version 4. It works quite differently, with many elements initialised with an array of |
Thanks, I'll see if I can get that up for you soon. |
I came across another Typescript thing. When using import { useFrame, useUpdate, Object3DNode, GeometryNode } from 'react-three-fiber';
// Module 'react-three-fiber/targets/web' has no exported member 'Object3DNode'
// ...
const Orbit = forwardRef<Object3DNode, OrbitProps>(({
// ...
}, ref) => {
const orbitRef = useRef<Object3DNode>();
// ...
const lineRef = useUpdate<GeometryNode>(geometry => {
// ...
});
return (
<group ref={ref} rotation={[ 0, inclination, 0]}>
<line>
<lineBasicMaterial attach="material" color={'lightgrey'} />
<geometry attach="geometry" ref={lineRef} />
</line>
<group ref={orbitRef}>
{children}
</group>
</group>
)
}); |
You should use the Object3D type and import it from three, example here https://github.com/react-spring/drei/blob/master/src/useHelper.tsx |
Ah, ok. got it. Make sense since So, for Geometry I would use the threejs class, too: import { Object3D, Geometry } from 'three';
// ...
const lineRef = useUpdate<Geometry>(geometry => { Thanks for your help! |
I'm not sure if this closes this whole issue 😅 |
I'm closing this specific issue since it's pretty dated to begin with, please open new specific issues when needed, it's easier for us to track |
Any interest in supporting TypeScript?
Initially probably only the inner workings (react-reconciler provides types) and then finding a way to generate types for the THREE bindings.
The text was updated successfully, but these errors were encountered: