How to set values for BufferAttribute? Documentation examples produce TS errors

Context

I followed instructions here for updating buffer attributes: three.js docs

The example seems to update the position attribute values by directly changing the BufferAttribute’s array.

const positions = line.geometry.attributes.position.array;

let x, y, z, index;
x = y = z = index = 0;

for ( let i = 0, l = MAX_POINTS; i < l; i ++ ) {

    positions[ index ++ ] = x; // TS Error
    positions[ index ++ ] = y; // TS Error
    positions[ index ++ ] = z; // TS Error

    x += ( Math.random() - 0.5 ) * 30;
    y += ( Math.random() - 0.5 ) * 30;
    z += ( Math.random() - 0.5 ) * 30;

}

The issue is that the positions[index] = val lines give me this Typescript error:

TS2542: Index signature in type 'ArrayLike<number>' only permits reading.

I came across an SO post about this TS error and the fix seems to be to use BufferAttribute.setXYZ

This was all on three@0.130.0 and @types/three@0.130.0


It then occurred to me that I should upgrade! Unfortunately it looks like it has only gotten more complicated on three@0.150.0 and @types/three@0.150.0 and now I get an error on this:

const positions = line.geometry.attributes.position.array;

Produces TS error:

TS2339: Property 'array' does not exist on type 'BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute'.
  Property 'array' does not exist on type 'GLBufferAttribute'.

Using BufferAttribute.setXYZ now also produces an error:

TS2339: Property 'setXYZ' does not exist on type 'BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute'.
  Property 'setXYZ' does not exist on type 'GLBufferAttribute'.

Questions

To be clear, the Javascript appears to work as expected, but the TS errors make me wonder if I’m doing something wrong. I perused the GitHub issues and this forum for this issue and didn’t find it but it did look like there is/was some refactoring in progress around BufferAttribute and InterleavedBufferAttribute so I’m wondering if this is just the fallout of that.

I think the root of my questions are:

  • should BufferAttribute.setXYZ be a TS error?
  • should BufferAttribute.array be a TS error?
  • if they are both correctly producing TS errors, is there some more better way to be updating the attribute values?

Thank you!

I can’t say something about TS but the code example has been updating here:

It is recommended to use the dedicated BufferAttribute interface when accessing with buffer data.

1 Like

You now have to cast as THREE.BufferAttribute

E.g.,

// using array
const positions = (geometry.attributes.position as THREE.BufferAttribute).array

// using setXYZ
;(geometry.attributes.position as THREE.BufferAttribute).setXYZ(1, 2, 3, 4)

More Info : TS2339: Property 'array' does not exist on type 'BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute'. · Issue #389 · three-types/three-ts-types · GitHub

3 Likes