title: Typescript: How to set method return value => subclass
body: <p>I have a parent class with two subclasses:</p>
  
  <pre><code>abstract class Point {
      public readonly x: number;
      public readonly y: number;
  
      constructor(x: number, y: number) {
          this.x = x;
          this.y = y;
      }
  
      diff(point: Point): Point {
          return this.update(this.x - point.x, this.y - point.y);
      }
      // many methods like diff(); and then...
  
      protected abstract update(x: number, y: number): Point;
  }
  
  
  
  class ImmutablePoint extends Point {
      protected update(x: number, y: number): Point {
          return new ImmutablePoint(x, y);
      }
  }
  
  
  
  class MutablePoint extends Point {
      public x: number;
      public y: number;
  
      protected update(x: number, y: number): Point {
          this.x = x;
          this.y = y;
          return this;
      }
  }
  
  
  const pointA: ImmutablePoint = new ImmutablePoint(10, 10)
  const pointB: ImmutablePoint = new ImmutablePoint(6, 2);
  </code></pre>
  
  <p>But <code>diff()</code> method returns a Point, not a ImmutablePoint</p>
  
  <pre><code>// Error: type 'Point' is not assignable to parameter of type 'ImmutablePoint'.
  const result: ImmutablePoint = pointA.diff(pointB);
  </code></pre>
  
  <p>I'm looking for a way to re-define the method signature on the subclass without writing a new implementation, is it possible?</p>
  
  <p>I also tried to make <code>diff()</code> return value <code>this</code> but it doesn't work because ImmutablePoint doesn't return <code>this</code> but a new ImmutablePoint</p>
  
  <p><a href="http://www.typescriptlang.org/play/#src=%20%20%20%20abstract%20class%20Point%20%7B%0D%0A%20%20%20%20%20%20%20%20public%20readonly%20x%3A%20number%3B%0D%0A%20%20%20%20%20%20%20%20public%20readonly%20y%3A%20number%3B%0D%0A%0D%0A%20%20%20%20%20%20%20%20constructor(x%3A%20number%2C%20y%3A%20number)%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20this.x%20%3D%20x%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20this.y%20%3D%20y%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20%20%20%20%20diff(point%3A%20Point)%3A%20Point%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this.update(this.x%20-%20point.x%2C%20this.y%20-%20point.y)%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20%2F%2F%20many%20methods%20like%20diff()%3B%20and%20then...%0D%0A%0D%0A%20%20%20%20%20%20%20%20protected%20abstract%20update(x%3A%20number%2C%20y%3A%20number)%3A%20Point%3B%0D%0A%20%20%20%20%7D%0D%0A%0D%0A%0D%0A%0D%0A%20%20%20%20class%20ImmutablePoint%20extends%20Point%20%7B%0D%0A%20%20%20%20%20%20%20%20protected%20update(x%3A%20number%2C%20y%3A%20number)%3A%20Point%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20ImmutablePoint(x%2C%20y)%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%0D%0A%0D%0A%0D%0A%0D%0A%20%20%20%20class%20MutablePoint%20extends%20Point%20%7B%0D%0A%20%20%20%20%20%20%20%20public%20x%3A%20number%3B%0D%0A%20%20%20%20%20%20%20%20public%20y%3A%20number%3B%0D%0A%0D%0A%20%20%20%20%20%20%20%20protected%20update(x%3A%20number%2C%20y%3A%20number)%3A%20Point%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20this.x%20%3D%20x%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20this.y%20%3D%20y%3B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20this%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%0D%0A%0D%0A%0D%0A%20%20%20%20const%20pointA%3A%20ImmutablePoint%20%3D%20new%20ImmutablePoint(10%2C%2010)%0D%0A%20%20%20%20const%20pointB%3A%20ImmutablePoint%20%3D%20new%20ImmutablePoint(6%2C%202)%3B%0D%0A%0D%0A%20%20%20%20%2F%2F%20Error%3A%20type%20&#39;Point&#39;%20is%20not%20assignable%20to%20parameter%20of%20type%20&#39;ImmutablePoint&#39;.%0D%0A%20%20%20%20const%20result%3A%20ImmutablePoint%20%3D%20pointA.diff(pointB)%3B%0D%0A" rel="noreferrer">Playground Link</a></p>