简体   繁体   中英

Is it possible to define the size of a Float32Array type in typescript?

I know that with tuples sizes of arrays can be defined. Not applicable to float32array which is a class itself though.

Can that somehow be done with float32arrays as well?

I tried const foo: FloatArray32[4] but that casts the type directly to the number. I also tried to check if types might be compatible:

let foo: [number, number, number, number];
foo = new Float32Array([1, 2, 3, 4]);

But they are not.

Changing all the types in my code to '[number, number, number, number];' (in my case I need a 4 float array for a point coordinate) is a possibility, although I would need to make changes in quite a lot of places in the code.

However, I was wondering if there might be a 'childtype' extending Float32Array type, where the number of the elements of the array can be fixed in the type.

Javascript typed arrays, are in fact, fixed length - see the docs for your example . The constructors in particular:

new Float32Array(); // new in ES2017 
new Float32Array(length);
new Float32Array(typedArray); 
new Float32Array(object); 
new Float32Array(buffer [, byteOffset [, length]]);

all have the length deducible on creation (that new first one creates an empty array with 0 elements. I guess it simplified some edge cases).

I'm not sure how you are determining the type, but as soon as you get an item from your array it will be converted to a number, the only number type available in JS - so looking at your log is misleading here. Take a look at the following static property:

 Float32Array.prototype.byteLength

Returns the length (in bytes) of the Float32Array. Fixed at construction time and thus read only.

This is the only thing that counts. If you still don't believe the docs, try logging a cell after you overflow it (easier with int8 - put 200 or something). This is relevant to your example - nothing is being converted to a number . The array object is a view in fixed length numbers - again, run your test with an Int8Array and try to assign 200 to the cell, and read the cell.

This is a view into raw data. If you extract it and make mathematical operations, you are now in JS realm and working with Numbers - but once you assign stuff back, you better make sure the data fits. You cannot get JS/TS to show you something like float32 in your console, but each cell of the array itself does have an exact byte length.

unfortunately , making the length a part of the type is non-trivial within the type system as far as I can tell since the length is a property determined in construction (even if static and read only) and not a part of the type. If you do want something like this a thin wrapper could do the trick:

class vec4 extends Float32Array {
    constructor(initial_values? : [number, number, number, number]) {
    initial_values? super(initial_values) : super(4);
    }
}

would do the trick. If you are willing to give up square brackets you can add index out-of-bound checking in the different methods (you can set in a fixed width array any cell, but it will do nothing, and retrieving it will yield undefined if out of bounds, which may be error prone):

get(index : number) {
    if(index > 4 || index < 0) ...
    return this.private_data[index];
}
set(index : number, value : number) {
    if(index > 4 || index < 0) ...
    this.private_data[index] = value;
}  

Of course, without LSP in JS/TS the array and your class are still interchangeable, so enforcement is really only done on construction, and only if you do not try to break your own code ( let foo : vec4; foo = new Float32Array([1, 2]); etc...).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM