无法分配给“X”,因为它是只读属性 (TS)

无法分配给“X”,因为它是只读属性(TS)

Cannot assign to ‘X’ because it is a read-only property (TS)

当我们尝试更改类或对象中的只读属性的值时,会出现错误“无法分配给‘X’,因为它是只读属性”。

要解决该错误,请删除readonly修饰符或使用类型断言来更改属性的值。

以下是使用类时如何发生错误的示例。

索引.ts
// 👇️ with classes class Employee { readonly country: string = 'Germany'; changeCountry() { // ⛔️ Error: Cannot assign to 'country' because it is a read-only property.ts(2540) this.country = 'Chile'; } }

这是使用对象时如何发生错误的示例。

索引.ts
// 👇️ with objects type Person = { readonly name: string; }; const obj: Person = { name: 'Bobby Hadz', }; // ⛔️ Error: Cannot assign to 'name' because it is a read-only property.ts(2540) obj.name = 'Frank';

这些示例使用
readonly
修饰符将类和对象属性设置为只读,这使得它们不可变。

readonly如果您有权访问代码,请删除修饰符

要解决该错误,readonly如果您有权访问设置该修饰符的代码,请删除该修饰符。

索引.ts
class Employee { country = 'Germany'; changeCountry() { this.country = 'Chile'; } } // ------------------------------------ type Person = { name: string; }; const obj: Person = { name: 'Bobby Hadz', }; obj.name = 'Frank';

使用类型断言来解决错误

如果您无法删除修饰符readonly但需要更改属性的值
readonly,则可以使用
类型断言

索引.ts
class Employee { readonly country: string = 'Germany'; changeCountry() { (this.country as any) = 'Chile'; } } // ------------------------------------ type Person = { readonly name: string; }; const obj: Person = { name: 'Bobby Hadz', }; (obj.name as any) = 'Frank';

我们使用类型断言将只读属性转换为any,以便能够更改它们的值。

您还可以更具体,并将readonly属性转换为赋值中值的类型。

索引.ts
class Employee { readonly country: string = 'Germany'; changeCountry() { (this.country as string) = 'Chile'; } } type Person = { readonly name: string; }; const obj: Person = { name: 'Bobby hadz', }; (obj.name as string) = 'Frank';
在某些情况下,当您使用第三方库并尝试更改不可变state对象时会发生错误。

如果这就是您所处的情况,则很可能库导出了一种用于改变其状态的方法,并且不应该直接通过更改对象来完成state

我还写了一篇关于
如何将只读属性更改为可变属性的详细文章。

使用受保护的类属性

如果您需要一个不能从外部更改且只能从类内部更改的类属性,请将该属性设置为protected并使用getter

索引.ts
class Employee { protected _country = 'Germany'; get country(): string { return this._country; } changeCountry() { this._country = 'Chile'; } } const employee = new Employee(); console.log(employee.country); // 👉️ "Germany" // ⛔️ Cannot assign to 'country' because it is a read-only property.ts(2540) employee.country = 'Belgium';

受保护的
类属性只能从类及其子类内部访问。

这就是为什么我们添加了一个允许从类外部访问的 getter。

_country用户不能直接从外部更改属性,但可以调用该changeCountry方法并将其设置为特定属性。

您还可以将该方法标记为受保护或从类的构造函数方法changeCountry更改
属性。
_country如何实现这一点取决于您的用例。

额外资源

您可以通过查看以下教程了解有关相关主题的更多信息: