-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ArrayTag Generic Types #43
Comments
Worked out yesterday how to accomplish this with a few builder types! It does everything I wanted to accomplish with it, and it really does help ensure type-safety. The only downside I've noticed with it so far though is that you can't validate with this type when you are creating a given typescript - How to remove index signature using mapped types - Stack Overflow type RemoveIndex<T extends object> = {
[K in keyof T as
string extends K
? never
: number extends K
? never
: symbol extends K
? never
: K
] : T[K];
};
type ExtractTuple<T extends any[]> = {
[Entry in keyof T as Entry extends `${number}` ? Entry : never]: T[Entry];
};
type ArrayTuple<TypedArray extends object, Tuple extends any[]> = RemoveIndex<TypedArray> & ExtractTuple<Tuple>;
type ArrayTag<ArrayLike extends object, Tuple extends any[] | ArrayLike> =
Tuple extends any[]
? ArrayTuple<ArrayLike, Tuple>
: ArrayLike;
type ByteArrayTag<T extends Int8Array[number][] | Int8Array = Int8Array> = ArrayTag<Int8Array, T>;
type IntArrayTag<T extends Int32Array[number][] | Int32Array = Int32Array> = ArrayTag<Int32Array, T>;
type LongArrayTag<T extends BigInt64Array[number][] | BigInt64Array = BigInt64Array> = ArrayTag<BigInt64Array, T>;
type Nice = ByteArrayTag;
type Nicer = ByteArrayTag<[number, 5]>;
declare const nice: Nice;
const hi = nice[110];
declare const nicer: Nicer;
// @ts-expect-error - `Array` methods shouldn't be present on this custom derived tuple type, since it's an `Int8Array`.
nicer.push;
const hello = nicer[1];
// @ts-expect-error - property shouldn't be indexable, it's not defined in the tuple generic.
nicer[5];
// Demos pt.2
// player position NBT type
type Pos = IntArrayTag<[number, number, number]>;
declare let pos: Pos;
pos[0];
pos[1];
pos[2];
// @ts-expect-error
pos[3];
// @ts-expect-error - this shouldn't be assignable to the tuple type
pos = new Int32Array() as IntArrayTag;
// comparing to regular tuple
type Lol = [0, 1, 2, 3];
declare const lol: Lol;
// @ts-expect-error - just like this isn't accessible
lol[5];
// Next demos after rehashing
// @ts-expect-error - How would one validate this, and get automatic type handling, withough needing to use `as` on the value? Can you add generics to existing interfaces?
const hii: LongArrayTag<[5n]> = new BigInt64Array([5n]); |
Looking into a few different ways to accomplish representing tuple types with
TypedArray
-based NBT key types.Right now the standard library types don't provide anything like tuple support for
TypedArray
values. I'd like to be able to do something likeInt8Array<[number, number]>
, and only allow access of those two properties, just like the regularArray
tuple type notation allows for ([number, number]
on it's own).I've encountered a few places where this would be a great help at type validation, namely things like player NBT UUID fields, which would be
IntArrayTag<[number, number, number, number]>
, as well as position tuple fields, which tend to be what would be described withIntArrayTag<[number, number, number]>
.The text was updated successfully, but these errors were encountered: