title: Caching constructor causing "Property '...' has no initializer and is not definitely assigned in the constructor."
body: <p>Every now and then in my projects, I create classes with constructors that cache the objects they create so that if the constructor is called with identical parameters multiple times, it returns the same instance each time instead of creating a new instance that would be identical to one already created. </p>
  
  <p>Here is a minimal example:</p>
  
  <pre><code>class X {
      private static __cache: Record&lt;string, X&gt; = Object.create(null);
  
      readonly name: string; // The compilation error happens on this line.
  
      constructor(name: string) {
          const cached = X.__cache[name];
          if (cached !== undefined) {
              return cached;
          }
  
          this.name = name;
          X.__cache[name] = this;
      }
  }
  </code></pre>
  
  <p>This code worked just fine with TypeScript, until I moved to 2.7 and turned on the <code>strictPropertyInitialization</code> . Now I get an error on <code>readonly name: string;</code> saying </p>
  
  <blockquote>
    <p>Property 'name' has no initializer and is not definitely assigned in the constructor.</p>
  </blockquote>
  
  <p>I have multiple classes with the pattern above in my projects so I need to come up with one or more general solutions to get rid of the error.</p>
  
  <p>Two solutions I don't want:</p>
  
  <ol>
  <li><p>Turn off <code>strictPropertyInitialization</code>. I find it too useful in general to turn it off. Turning it on showed some definitions that needed to be updated to better reflect how some of my classes work, or prompted improvements in initialization code.</p></li>
  <li><p>Add a definite assignment assertion to <code>name</code> so that it is declared as <code>readonly name!: string;</code>. The exclamation point causes TypeScript to no longer check whether <code>name</code> is definitely assigned. This removes the error but it is also punching too big a hole in the compiler checks for my taste. For instance, if I use the assertion and I ever accidentally drop the assignment <code>this.name = name</code> in the code above, then TypeScript won't raise an error. I like to be notified early of mistakes.</p></li>
  </ol>
  
  <p>I presented a minimal example above but in my applications I have classes with many more fields, or fields that are created from significantly expensive computations rather than just being assigned from constructor parameters.</p>