TypeScript中能否向readonly类成员数组执行push/pop操作?
Short answer: Yes, you absolutely can—calling pop(), push(), or other array mutation methods on foo.arr is totally allowed, even with the readonly modifier on the class property. Let me explain why this works, and how to lock down the array completely if that's your goal.
Why mutation is permitted
The readonly keyword on a class property only restricts reassigning the property to a new value. It doesn't make the array itself immutable.
In your code:
class Foo { public readonly arr: number[] constructor(arr: number[]) { this.arr = arr } }
foo.arr = [1,2]throws an error because you're trying to redirect thearrproperty to a new array object—that's exactly whatreadonlyprevents.- But
foo.arr.push(4)is totally okay: you're not changing which arrayarrpoints to, you're just modifying the contents of the existing array it references.
Here's a quick code example to show this in action:
const foo = new Foo([1,2,3]); foo.arr.push(4); // No TypeScript errors here! console.log(foo.arr); // Outputs [1,2,3,4] foo.arr = [5,6]; // Error: Cannot assign to 'arr' because it is a read-only property.
How to make the array truly immutable
If you want to stop all mutations to the array (including push()/pop()), you need to change the array's type to a read-only array. You have two options for this:
- Use
readonly number[]as the property type (the modern, concise syntax) - Use
ReadonlyArray<number>(the older, more explicit alternative)
Here's how that looks in code:
class Foo { public readonly arr: readonly number[] constructor(arr: number[]) { this.arr = arr } } const foo = new Foo([1,2,3]); foo.arr.push(4); // Error: Property 'push' does not exist on type 'readonly number[]'.
Now TypeScript will block any mutable array methods, since readonly number[] only exposes read-only methods like map or slice.
内容的提问来源于stack exchange,提问作者Bovard

