After updating typings to @types/ 16.4.4. we got set of these errors:
error TS2540: Cannot assign to 'state' because it is a constant or a read-only property.
The code that was broken:
constructor(props) {
super(props);
this.state = {
stateProperty: initialValue
}
}
The fix is to use
constructor(props) {
super(props);
this.setState({
stateProperty: initialValue
});
}
Previous version we used was @types/ 16.0.40
ReadOnly property should be allowed to set in a constructor.
Authors: @johnnyreilly, @bbenezech, @pzavolinsky, @digiguru, @ericanderson, @morcerf, @tkrotoff, @DovydasNavickas, @onigoetz, @theruther4d, @guilhermehubner, @ferdaber, @jrakotoharisoa
Looks to be introduced in https://github.com/DefinitelyTyped/DefinitelyTyped/pull/26813
+1
Actually that is not a fix... https://github.com/DefinitelyTyped/DefinitelyTyped/pull/26813#issuecomment-400795486 is the correct fix
Yeah. v16.4.2 of the type definitions is still working fine when v16.4.4 just breaks a lot of existing codebase in my project.
+1
The fix I suggested is not entirely correct as it is stated here and the reason is React documentation
PRs welcome folks! Ping me and I'll review...
+1
+1.
The null here also introduce errors when using react redux connect().
state: null | Readonly<S>;
In summary, derived class loses the ability to declare a non-null state. strictNullChecks will expose the problem.
Please dont add the null back in the future. typings are tools to make life easier, not harder.
Consider a plain class:
class Apple {
state: {taste: string};
constructor() {
this.state = {
taste: "sweet",
};
}
yearsLater(): void {
console.log(this.state.taste);
}
}
I can declare a non-null state and initialize it in my constructor. everything is fine.
Then turn it into a 16.4.4 react component.
class Apple extends React.Component<{}, {taste: string}> {
constructor(props: Readonly<{}>) {
super(props);
this.state = {
taste: "sweet",
};
}
yearsLater(): void {
console.log(this.state.taste); // [ts] Object is possibly 'null'
}
}
I got a compile-time error. How to tell React.Component that my state is not null and I WILL initialize it in constructor ?
Let's use an example from react official doc: https://reactjs.org/docs/state-and-lifecycle.html
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
How to write such code in typescript with strictNullChecks=true?
Fixed in 16.4.6
Most helpful comment
Yeah.
v16.4.2of the type definitions is still working fine whenv16.4.4just breaks a lot of existing codebase in my project.