Open vbraun opened 4 years ago
I have the same error using https://overmindjs.org
Basically I have the following 2 files in a directory:
export const x: number = 100
import { Action } from 'overmind'
export const setData: Action<number> = ({ state }, x: number) => {
state.data.x= x
}
And it gives me an error (red-squiggly lines) on state.data.x
stating
Cannot assign to 'x' because it is a read-only property.ts(2540)
If I change the x
from const
to let
, it goes away. I have no idea how those 2 are related but must be some Overmind magic.
Edit: I solved this issue. The reason was that I didn't change one of my Overmind methods from JavaScript to TypeScript. Once I changed it to TypeScript, this error was gone. Seems like my issue, not a compiler one :)
In the checker, I found the following comment
// Allow assignments to readonly properties within constructors of the same class declaration.
Based on the example, this.x
is not related to Foo
, that's why TS shows the error.
if (isBar(this)) {
// error TS2540: Cannot assign to 'x' because it is a read-only property.
this.x = 'string';
}
I'm not sure whether to allow property assignment not only for the same class declaration. @RyanCavanaugh @DanielRosenwasser Could you clarify that case?
At runtime there really is only one property we could be talking about, so there needs to be a more local search - but this code is super sketchy now that I look at it. It's going to not work under useDefineForClassFields
...
Using a type assertion on the object whose property is to be assigned triggers this error, too (TS 5.5.2):
class Baz<T extends string | number> {
readonly isString: T extends string ? true : false
constructor(t: T) {
if (typeof t === 'string') {
(this as Baz<string>).isString = true
} else {
(this as Baz<number>).isString = false
}
}
}
A common pattern is declaring narrower types for members in derived classes. However, when combined with type guards, assignement to readonly members fails with an unexpected "Cannot assign to ... because it is a read-only property" error.
TypeScript Version: 3.7.2
Search Terms: class member read-only property type narrowing covariant type guard
Code
Expected behavior:
Assignment to this.x should be allowed with or without type guard in the constructor
Actual behavior:
error TS2540: Cannot assign to 'x' because it is a read-only property.
Playground Link:
https://www.typescriptlang.org/play/?ssl=2&ssc=1&pln=22&pc=1#code/FAYwNghgzlAEBiB7RsDexadgBwK4CMwBLEWAJwFMIATRAOzAE9YAPALligBcyi6BzWAB9YdXAFt8FMgG5gGLCHrcyuEF0RkAFAEo0CrFiIAzWFqJQAQhG1cAFhZ06Dh1wHo3saWU2wAKgDKAEwArAAsAAwcAMIQdHSIXLDQUET8dLAasADkLNmwUiAQuFAUsERJFsnkVNQAtPRMOD7Y0lyMAHQurlj2Fh0ssAC8sACMQQDMcj2YFGCl3TMeoijevnbSFIs9fVADw2OT01gAvsBnoJAwsNZkXixcFHTUcEgo6IZ4hCQ1NI3M7E4PD4-DkF2MuDo6iI9HKVhsWmMyA4bx0HCRKCqt30hkoXFwZAyGPKdG4cRAFEQpluYOAQA
Related Issues:
It is as if the type guard creates an invisible alias (cf https://github.com/microsoft/TypeScript/issues/14241), and asignment inside the type guard fails.