Whenever I work on projects, I tend to create classes with constructors that cache the objects they generate. This way, if the constructor is called with the same parameters multiple times, it will return the same instance rather than creating redundant instances.
Let's take a look at a simple example:
class X {
private static __cache: Record<string, X> = Object.create(null);
readonly name: string; // A compilation error occurs here.
constructor(name: string) {
const cached = X.__cache[name];
if (cached !== undefined) {
return cached;
}
this.name = name;
X.__cache[name] = this;
}
}
This code used to work flawlessly in TypeScript until I upgraded to version 2.7 and enabled strictPropertyInitialization
. Now, an error pops up on readonly name: string;
stating:
Property 'name' has no initializer and is not definitely assigned in the constructor.
I have several classes in my projects following this pattern, so I need to come up with some general solutions to eliminate the error.
Two solutions I am not keen on:
Disabling
strictPropertyInitialization
. Although useful, I prefer not to turn it off as it revealed areas needing improvement and forced me to update definitions in some cases.Adding a definite assignment assertion to
name
, likereadonly name!: string;
. While this bypasses the error, it also weakens compiler checks. If I accidentally miss the assignmentthis.name = name
, TypeScript won't flag it as an error - which is risky for catching mistakes early.
The example provided was minimal, but in actual applications, classes may have numerous fields or involve complex computations rather than simple parameter assignments.