-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Support for Read-only Typed Arrays #37792
Comments
You can do this today with existing type system features; I don't think this necessitates defining something built-in. |
Do you mind explaining how? Nothing I did worked to be able to return read-only typedarrays |
No answer or clarification prior to closing? |
@ImBoop If you're not sure how to accomplish some task, that's a question, and this isn't a support forum. If you want to show more explicitly what you were trying to do and what wasn't working with it, we can often advise. |
@RyanCavanaugh But you can't do this with existing types... At least, not without manually and carefully defining all the methods that can operate on readonly typed array. TypeScript already defines |
This was the bulk of the issue -- it required recreating the entire class and even then you'd run into issues where your type couldn't be used without a headache inducing process as the readonly typed array would have to omit methods that wrote to said array. I ended up not following up with their comment because I felt that the closing of it without comment was very unprofessional -- mainly because I didn't see his edit as I saw the comment via email (nevermind that they claimed it was possible without backing it up...) As a usecase and clarified proposal I guess: Typed arrays are often far better in terms of performance compared to standard arrays (which can be sparse which is why I presume they can be slower) The benefit of a readonly typed array is for, at least in my use case when this was created, making sure the caller couldn't modify a block of data without using a method e.g., a Like ReadonlyArray, this would remove methods that could alter the array from the definition (which, notably, is where a lot of issues you'd run into would come into play if you wanted to use the two types together) such as The idealistic proposal would also support using the |
Here is a workaround based on https://www.growingwiththeweb.com/2020/10/typescript-readonly-typed-arrays.html /**
* Typeds array mutable properties.
*/
type MutableProperties = "copyWithin" | "fill" | "reverse" | "set" | "sort";
/**
* Describes a `Uint8ClampedArray` that can only be read from.
* Any variable with a reference to a `ReadonlyUint8ClampedArray` can’t add, remove,
* or replace any elements of the array.
*/
export interface ReadonlyUint8ClampedArray extends Omit<Uint8ClampedArray, MutableProperties> {
readonly [n: number]: number;
}
/**
* Describes a `Uint8Array` that can only be read from.
* Any variable with a reference to a `ReadonlyUint8Array` can’t add, remove,
* or replace any elements of the array.
*/
export interface ReadonlyUint8Array extends Omit<Uint8Array, MutableProperties> {
readonly [n: number]: number;
}
/**
* Describes a `Uint16Array` that can only be read from.
* Any variable with a reference to a `ReadonlyUint16Array` can’t add, remove,
* or replace any elements of the array.
*/
export interface ReadonlyUint16Array extends Omit<Uint16Array, MutableProperties> {
readonly [n: number]: number;
}
/**
* Describes a `Uint32Array` that can only be read from.
* Any variable with a reference to a `ReadonlyUint32Array` can’t add, remove,
* or replace any elements of the array.
*/
export interface ReadonlyUint32Array extends Omit<Uint32Array, MutableProperties> {
readonly [n: number]: number;
}
/**
* Describes a `Int8Array` that can only be read from.
* Any variable with a reference to a `ReadonlyInt8Array` can’t add, remove,
* or replace any elements of the array.
*/
export interface ReadonlyInt8Array extends Omit<Int8Array, MutableProperties> {
readonly [n: number]: number;
}
/**
* Describes a `Int16Array` that can only be read from.
* Any variable with a reference to a `ReadonlyInt16Array` can’t add, remove,
* or replace any elements of the array.
*/
export interface ReadonlyInt16Array extends Omit<Int16Array, MutableProperties> {
readonly [n: number]: number;
}
/**
* Describes a `Int32Array` that can only be read from.
* Any variable with a reference to a `ReadonlyInt32Array` can’t add, remove,
* or replace any elements of the array.
*/
export interface ReadonlyInt32Array extends Omit<Int32Array, MutableProperties> {
readonly [n: number]: number;
}
/**
* Describes a `Float32Array` that can only be read from.
* Any variable with a reference to a `ReadonlyFloat32Array` can’t add, remove,
* or replace any elements of the array.
*/
export interface ReadonlyFloat32Array extends Omit<Float32Array, MutableProperties> {
readonly [n: number]: number;
}
/**
* Describes a `Float64Array` that can only be read from.
* Any variable with a reference to a `ReadonlyFloat64Array` can’t add, remove,
* or replace any elements of the array.
*/
export interface ReadonlyFloat64Array extends Omit<Float64Array, MutableProperties> {
readonly [n: number]: number;
}
/**
* Describes a `BigInt64Array` that can only be read from.
* Any variable with a reference to a `ReadonlyBigInt64Array` can’t add, remove,
* or replace any elements of the array.
*/
export interface ReadonlyBigInt64Array extends Omit<BigInt64Array, MutableProperties> {
readonly [n: number]: bigint;
}
/**
* Describes a `BigUint64Array` that can only be read from.
* Any variable with a reference to a `ReadonlyBigUint64Array` can’t add, remove,
* or replace any elements of the array.
*/
export interface ReadonlyBigUint64Array extends Omit<BigUint64Array, MutableProperties> {
readonly [n: number]: bigint;
} |
Fantastic workaround and good find. Disappointed that the TS team continues to stick their head in the mud with this issue, but this will be very useful for those that find this issue in the future, with the notable caveat that if TypedArrays are extended in the future with other methods that write to it, it will stop (fully as intended, anyway) working (hence the purpose of this issue to begin with, for first class support of the types a la readonly arrays have.) |
@yvele Thanks for posting the workaround! Would love to see this implemented natively. |
@RyanCavanaugh @RReverser Any plans to reopen this issue, as it's clearly not resolved? |
The workaround can be made less brittle by declaring type MutableProperties = Exclude<keyof unknown[], keyof readonly unknown[]> It's very likely that any new mutation methods added to typed arrays will also be added to regular arrays, so this should be future-proof. Note that this also gets some keys like |
I wanted a proper readonly TypedArray, came to see if there is a built-in version similar to arrays, and got the answer that there isn't. Imho, the issue is indeed resolved, and the answers were on point. I'll will write one myself, or use a library, and don't see a big problem with it. While it would have been nice, if TS had a built-in readonly TypedArray, as has been detailed, there is no necessity for it. Outsourcing the maintenance of such utility types means the resources otherwise used for it can be allocated for more important things. Overall, I agree with that decision. There are far more important issues open, and this can be solved without additions to TS itself. |
@yvele @kaya3 Thanks for the great workarounds! A couple of thoughts:
|
And it's still mutable through the 3-rd argument of every/filter/find etc. It seems like a better solution would be recreating original typed array api with readonly tweaks and removal of all mutating methods. Like this https://gist.github.com/Cinderlex/167a8e18afb8da15f03358ced695a3af . It also seems to become mutable counterpart's supertype (cause structural typing). |
Remember, just because it doesn't require any new language features doesn't mean it that it shouldn't be in the standard library ... |
Search Terms
ReadonlyTypedArray Int8Array Uint8Array Uint16Array Int16Array Uint32Array Int32Array Float32Array Float64Array
Suggestion
It would be nice if we had readonly or otherwise immutable typed arrays.
Use Cases
I would like to return my array directly for performant bulk access to the data within, but make sure only the methods on the object itself are used to alter it.
Examples
Ideally it'd be just like ReadonlyArray, in that you'd return ReadonlyTypedArray
I tried the following workaround:
This, as expected, only has the indexing available, none of the methods/fields available in T are accessible (and if you use & instead of |, it doesn't override the indexing operator)
My current workaround is to do this:
Like ReadonlyArray, this would only be a static readonly enforcement, not runtime.
Checklist
My suggestion meets these guidelines:
The text was updated successfully, but these errors were encountered: