title: Polymorphism and type-safety with "decoupled" classes
body: <p>In my code, I have certain types of classes for different photo collection types and each comes with a service class that manages it (due to the architecture of the overall application, I've to stick to that).</p>
  
  <p>That's the code in a simplified version:</p>
  
  <pre class="lang-js prettyprint-override"><code>interface ICollection {}
  
  class ImportedCollection implements ICollection {}
  class CustomCollection implements ICollection {}
  
  class ImportedCollectionsService {
    findPhotos(collection: ImportedCollection) {
      console.log('ImportedCollectionsService.findPhotos');
    }
  }
  class CustomCollectionsService {
    findPhotos(collection: CustomCollection) {
      console.log('CustomCollectionsService.findPhotos');
    }
  }
  
  ////////////////////////////////////////////////////////
  
  const importedCollectionsService = new ImportedCollectionsService();
  const customCollectionsService = new CustomCollectionsService();
  
  const collection: ICollection = new ImportedCollection();
  
  ////////////////////////////////////////////////////////
  
  if (collection instanceof ImportedCollection) {
    importedCollectionsService.findPhotos(collection);
  } else if (collection instanceof CustomCollection) {
    customCollectionsService.findPhotos(collection);
  }
  </code></pre>
  
  <p>Stackblitz: <a href="https://stackblitz.com/edit/typescript-ydp7xn?file=index.ts" rel="nofollow noreferrer">https://stackblitz.com/edit/typescript-ydp7xn?file=index.ts</a></p>
  
  <p>It works and it's theoretically type-safe, but I'm not happy with the <code>instanceof</code> at the end of the snippet. Instead, I'd like to go for a more polymorphism-oriented approach for more flexibility (i.e. to have all code for a specific collection type at the same place).</p>
  
  <p>Ideally, I'd get rid of the <code>instanceof</code> check entirely, but I don't know if that's even possible. Alternatively, a solution that at least encapsulates the check would be acceptable.</p>
  
  <p>I tried around a bit and got to this code: <a href="https://stackblitz.com/edit/typescript-vo5yb1" rel="nofollow noreferrer">https://stackblitz.com/edit/typescript-vo5yb1</a>
  By using a (generic) interface, I can enforce all service classes to implement the <code>findPhotos</code> method with a collection-specific parameter, but I lose type-safety in line 40 (<code>collection</code> being casted to <code>any</code>).</p>
  
  <p>If I let <code>findPhotos</code> accept a parameter of type <code>ICollection</code> instead, I'd just move the type-safety issue into the <code>findPhotos</code> method (which needed to do a type assertion as I need the more-specialized collection type within the method).</p>
  
  <p>Is there a TypeScript feature or better architecture that allows me to fix these problems or should I better just stick to the original version).</p>
  
  <p>Best regards</p>