bitECS icon indicating copy to clipboard operation
bitECS copied to clipboard

Improve array type component TS typedefs

Open EnderShadow8 opened this issue 4 years ago • 7 comments

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 😅

EnderShadow8 avatar Aug 25 '21 07:08 EnderShadow8

this is neat! but there are 2 issues, correct me if i'm wrong:

  1. the compiler will obfuscate the real underlying type of TypedArray and its own suite of methods such as set, subarray, etc which Array type does not have
  2. gives a false sense of security, as now Array methods such as push will not work despite the compiler allowing it

NateTheGreatt avatar Aug 25 '21 16:08 NateTheGreatt

@NateTheGreatt

  1. the compiler will obfuscate the real underlying type of TypedArray and its own suite of methods such as set, subarray, etc which Array type does not have
  1. gives a false sense of security, as now Array methods such as push will 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

image

EnderShadow8 avatar Aug 26 '21 00:08 EnderShadow8

@EnderShadow8 here is a screenshot of what I meant (with your typings applied): image 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 avatar Sep 27 '21 21:09 NateTheGreatt

@NateTheGreatt

@EnderShadow8 here is a screenshot of what I meant (with your typings applied): image 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.

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
}

EnderShadow8 avatar Sep 28 '21 00:09 EnderShadow8

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

NateTheGreatt avatar Sep 29 '21 21:09 NateTheGreatt

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

dannyfritz avatar Oct 02 '21 23:10 dannyfritz

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:

NateTheGreatt avatar Oct 04 '21 03:10 NateTheGreatt