bitECS
bitECS copied to clipboard
Improve array type component TS typedefs
Nobody asked for this, but I thought it would be a nice to have.
Array type components can now hold information about their length and disallow out of bounds indexing. The caveat being the requirement to prepend readonly or append as const to the array type in the schema. Without this, it defaults to the old typings.
const cmp = defineComponent({
vec2: [Types.f32, 2] as const,
vec3: readonly [Types.f32, 3],
})
// Old types
{
vec2: Float32Array[],
vec3: Float32Array[],
}
// New types
{
vec2: ArrayType<Float32Array, 2>[],
vec3: ArrayType<Float32Array, 3>[],
}
I'm sorry if the types are a little crazy 😅
this is neat! but there are 2 issues, correct me if i'm wrong:
- the compiler will obfuscate the real underlying type of
TypedArrayand its own suite of methods such asset,subarray, etc whichArraytype does not have - gives a false sense of security, as now
Arraymethods such aspushwill not work despite the compiler allowing it
@NateTheGreatt
- the compiler will obfuscate the real underlying type of
TypedArrayand its own suite of methods such asset,subarray, etc whichArraytype does not have
- gives a false sense of security, as now
Arraymethods such aspushwill not work despite the compiler allowing it
ArrayType is defined as an intersection of the TypedArray, minus the number index signature, and a mapped type containing all valid keys 0, 1, 2, 3, 4 ... length - 1. So all TypedArray properties still exist, and it's not intersected with an Array or Tuple anywhere.
Unless I misunderstood your objections though
Also not sure whether this is a problem, should be ok when you start typing

@EnderShadow8 here is a screenshot of what I meant (with your typings applied):
all of these highlighted properties (flat, push, pop, etc) do not exist on TypedArrays, despite the compiler allowing it with these array types you introduced
additionally, there are TypedArray-specific methods that Array does not have being obfuscated by the introduced typings. subbarray, set, etc, should show up in that list, but they don't.
@NateTheGreatt
@EnderShadow8 here is a screenshot of what I meant (with your typings applied):
all of these highlighted properties (
flat,push,pop, etc) do not exist on TypedArrays, despite the compiler allowing it with these array types you introducedadditionally, there are TypedArray-specific methods that
Arraydoes not have being obfuscated by the introduced typings.subbarray,set, etc, should show up in that list, but they don't.
If I'm not mistaken, ColorComponent.colorMatrix is an Array of TypedArrays, so everything is correct here.
// Storage.js
const createArrayStore = (metadata, type, length) => {
const size = metadata[$storeSize]
const store = Array(size).fill(0)
// ^
...
return store
}
hahah okay ignore me, you're right @EnderShadow8. i misunderstood. i'm also in the middle of a refactor and confused myself. i have been trying to figure out how to limit the use of those functions entirely... ideally these functions shouldn't be allowed to be called at all.
e.g. we don't want the user to be able to do any of this:
const cmp = defineComponent({
vec2: [Types.f32, 2],
})
cmp.vec2.push(new Float32Array(2))
cmp.vec2[0] = new Float32Array(2)
if you could limit these calls in your typings that would be great, but i also want to somehow prevent it in raw JS as well
if you could limit these calls in your typings that would be great, but i also want to somehow prevent it in raw JS as well
Would this be suitable? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#freezing_arrays
if you could limit these calls in your typings that would be great, but i also want to somehow prevent it in raw JS as well
Would this be suitable? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#freezing_arrays
nice, i didn't realize that freeze applied this way to arrays!
let's freeze them in this PR, and if the typings could be updated to reflect that then i think i'd be okay merging this :+1: