2

I would like to write correct types for the Mesh Vertices and Faces.

In the first example, I create a new Mesh, and when I want to access Vertices and Faces from geometry, I get a few errors:

const material = new THREE.MeshLambertMaterial({color: 0x00ff00});
const geometry = new THREE.Geometry();
const newMesh = new THREE.Mesh(geometry, material);
scene.add(newMesh);

const { vertices, faces } = newMesh.geometry;
// Error: Property 'vertices' does not exist on type 'BufferGeometry | Geometry'
// Error: Property 'faces' does not exist on type 'Geometry | BufferGeometry'.

newMesh.geometry.colorsNeedUpdate = true;
// Error: Property 'colorsNeedUpdate' does not exist on type 'Geometry | BufferGeometry'.

In the second example, I get Mesh from the Scene, and then I get the following error:

const mesh = scene.getObjectByName('boxMesh');
const geometry = mesh.geometry; 
// Property 'geometry' does not exist on type 'Object3D'.

1 Answer 1

3

By accessing the geometry via the mesh (newMesh.geometry) you get the geometry typed like the geometry property on the Mesh class. Apparently the property supports two different types of geometry so you get a union: Geometry | BufferGeometry.

If you know exactly what type of geometry is used you can just assert the type of the property value:

const { vertices, faces } = <THREE.Geometry>newMesh.geometry;

If you do not know the type of geometry you need some conditional logic, e.g. using something like:

const geometry = newMesh.geometry;
if (geometry instanceof THREE.Geometry)
    // geometry will be typed as Geometry here
else
    // geometry will be typed as BufferGeometry here

In the second case you use getObjectByName which always returns objects of the most basic type Object3D. Here you also have to assert the type of the result accordingly.

// Assuming the thing named boxMesh is a Mesh...
// The <any> assertion prevents additional type errors.
const mesh = <THREE.Mesh><any>scene.getObjectByName('boxMesh');
Sign up to request clarification or add additional context in comments.

6 Comments

When I write like this: const mesh = <THREE.Mesh>scene.getObjectByName('boxMesh'); I het error: "Type 'Object3D | undefined' is not assignable to type 'Mesh | undefined'. Type 'Object3D' is missing the following properties from type 'Mesh': geometry, material,"
For errors like this you can first assert it as any: <THREE.Mesh><any>scene.getObjectByName('boxMesh');
There should be a better solution than to use any
Well, there isn't. The function getObjectByName should not return Object3D in the first place but have a generic parameter deriving from Object3D, so you could specify the return type in the function call. Casting to any first is the standard way of solving this issue (see double assertion section in documentation).
@john_per Actually, the single type assertion should work in this case because Mesh is a subtype of Object3D. I tried it myself and do not get any errors, Are you using the wrong Mesh class?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.