无法分配给“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
如何实现这一点取决于您的用例。
额外资源
您可以通过查看以下教程了解有关相关主题的更多信息: