I would like to have constant (readonly) properties in a React.Component class. The problem is that I should not initialize them in the constructor since they trigger side effects like setInterval or fetch. Instead I should initialize them in componentDidMount but since I use strict type checkings I must also indicate their types can be undefined (or null, whatsoever). That's what I want to avoid because then I am forced to check if the value is not null every time I use it despite I know it already, and I also wanna avoid using the "!" operator as much as possible because then I don't have type errors when I forget to initialize them.
Does there exist a clean solution? Some way to tell typescript that componentDidMount is like a constructor and so a property can be initialized only there?
No, there is no clean way to do this. It's inherent to TypeScript's understanding of classes that there are roughly two areas of the class (ignoring errata not relevant to the question):
Taking a step back: knowing that componentDidMount
is an initialization function is something like a "hidden assumption" in code. That is, it's not a part of JavaScript itself and nothing in the code itself explains it. It's something you're expected to know when working with React classes. The type system not having a good tool for this is because it'd be very difficult to describe in type-system-land the nuances of each framework's magic.
Having to memorize these hidden assumptions is part of why many developers have moved to React function components. They don't have a need to mutate the types of properties over time - it's more around variables and scoping, which fit better into type systems.