Covariant _this type

Topics: General
Oct 7, 2012 at 12:14 PM
Edited Oct 7, 2012 at 12:17 PM

"chaining" APIs are popular (and cool) in JavaScript and it would be nice to have a _this type to handle them seamlessly with class hierarchies.

Consider the following example:

 

interface Base {
  m1() : Base; // returns this for chaining
}

interface Derived extends Base {
  m2(): Derived; // returns this for chaining
}

new Derived().m2().m1(); // works
new Derived().m1().m2(); // error: m2 not defined in Base

 

Would be nice to be able to type all these interface elements as returning _this rather than Base/Derived.

Note: this feature exists in Eiffel (like Current). It has some issues (the "catcall" problem) but I have the impression that the issue goes away if we only allow it on return types (not on parameter types).

I got around the problem in my APIs by typing the return as "any" but then I lose all type checking in the remainder on the chain.

Oct 7, 2012 at 4:44 PM

I actually think this is a bug!

Coming from the other typed javascript land (closure tools), I think it is only natural for a compiler to be able to understand the type of the instance that is calling prototype methods. In the example provided it is obvious that the m1 method called is called with 'this' being an instance of the subclass and that it is called as a method, so basically the compiler should be able to determine that in this case the returned object is no longer the one set in the method definition (or for that mater, the inferred one), because it was actually invoked in in another class using the prototype chain.


I believe this should be fixed.

Can someone from the team confirm that it is a bug?

Thanks

Oct 7, 2012 at 6:51 PM

@pstj

You mean that the `Base` return type should be implicitly covariant. Would work but it may a bit too permissive (accept Derived in contexts where the developer really means Base).

Consider:

interface Node {
  next() : Node; 
  fooAndChain() : _this;
}
interface Node1 extends Node {}
interface Node2 extends Node {}

if obj is a Node1:

  • obj.next() may return a Node1 or a Node2
  • obj.fooAndChain() may only return a Node1

Would be nice to have the ability to distinguish between the two.

 

Oct 7, 2012 at 7:26 PM
Edited Oct 7, 2012 at 7:42 PM

Well, I was hoping that the compiler can derive the type based on the actual code and not only by the type annotation: considering the following code:

class ANode {
  private next_: ANode;
  setNode(next: ANode):void {
    this.next_ = next;
  }
  next(): ANode {
    return this.next_;
  }
}

class Node1 extends ANode {
  method1(): Node1 {
    return this;
  }
}

class Node2 extends ANode {
  method2(): Node2 {
    return this;
  }
}

var a = new Node1();
var b = new Node2();
a.setNode(b);

a.next().method2();

It is clear that this is valid and believed the compiler should be able to determine that the type returned by 'next' is actually Node2 and that it only checks if it is a valid 'ANode' interface (and it should be because it extends ANode) but still consider its real type (Node2).

 

However it seems the compiler is casting the returned item type to the one defined. Bummer.

 

This is why I think this is a bug or at least should be a feature request: The returned type should be Node2 and only checked if it matches the type definition (ANode) instead of being considered ANode. If this is not fixed lots of code will not be possible to be type checked because this is a widely used pattern.

Oct 7, 2012 at 8:01 PM

@pstj you can do what you're trying to do in TypeScript but you have to do it with interfaces.  Here's one approach to creating a chainable library that can be extended with plugins:

// Base library
class MyLib {
	public method1(): IMyLib { return this; }
	
	static create(): IMyLib {
		return <any>new MyLib();
	}
}

interface IMyLib {
	method1(): IMyLib;
}

// Extend library with a plugin
MyLib.prototype['method2'] = function (): IMyLib { return this; };

interface IMyLib {
	method2(): IMyLib;
}

var lib = MyLib.create();
lib.method1().method2().method1();

 

This is leveraging the fact that interfaces are open in TypeScript and this is one of the key scenarios they had in mind for interfaces.  There are a number of ways you could approach extending MyLib's prototype with your plugins methods but the main point is that to get the fluid style approach you're wanting you're going to need to use interfaces.

  

Oct 7, 2012 at 8:30 PM
Edited Oct 7, 2012 at 8:31 PM

Let me restate the problem with classes (I described it with interfaces because I was writing definitions for existing JS code). Consider:

 

class Base {
  m() { return this }; // returns this for chaining
}

class Derived1 extends Base {
  m1() { return this } // returns this for chaining
}

class Derived2 extends Base {
  m2() { return this } // returns this for chaining
}

function foo(d1: Derived1, d2: Derived2) { d1.m1().m1().m(); // works d2.m2().m2().m(); // works d1.m().m1(); // error: m1 not defined in Base d2.m().m2(); // error: m2 not defined in Base
}

The compiler cannot infer that m() returns a Derived1 when applied to a Derived1 (*). So, unless we have a type annotation like _this, we cannot solve the problem.

The interface solution would be a kludge. It would force us to put all methods (m, m1 and m2) into a single interface.

(*) Consider the following:

class BreaksChain extends Derived1 {
  m() { return new Derived2(); } 
}
Oct 7, 2012 at 8:37 PM
Edited Oct 7, 2012 at 9:05 PM

I see... Yes that looks like an issue worth raising.

Oct 8, 2012 at 8:30 AM

but this example would work, right?

 

 

class Base {
  public self;
  constructor() { this.self = this; }
  m() { return this.self }; // returns this for chaining
 
}

class Derived1 extends Base {
  m1() { return this.self } // returns this for chaining
}

class Derived2 extends Base {
  m2() { return this.self } // returns this for chaining
}

function foo(d1: Derived1, d2: Derived2) {
  d1.m1().m1().m(); // works
  d2.m2().m2().m(); // works
  d1.m().m1(); // works, because of self
  d2.m().m2(); // works, because of self
}


 

 

Oct 8, 2012 at 9:21 AM
Edited Oct 8, 2012 at 9:24 AM

It works but it is way too permissive. The corresponding definitions are:

 

class Base {
    public self;
    constructor ();
    public m();
}
class Derived1 extends Base {
    public m1();
}
class Derived2 extends Base {
    public m2();
}
function foo(d1: Derived1, d2: Derived2): void;

 

So self, m, m1 and m2 are typed as "any". The "because of self" comment is misleading, it should be "because of any". Try:

 

function foo(d1: Derived1, d2: Derived2) { 
d2.m().m3(); // works, although it should not
}

 

What I'm proposing is:

class Base {
    public m() : _this;
}
class Derived1 extends Base {
    public m1() : _this;
}
class Derived2 extends Base {
    public m2() : _this;
}
Oct 8, 2012 at 9:54 AM

This is not the use case discussed in this thread: We are instead discussing the fact that the compiler does not understand/remembers the type of the object that is the 'this' pointer in the method calls. I know how to overcome the limitation, but it leads to ugly code. This is not what should the objective be in TypeScript, we have enough spaghetti in JavaScript no need to port those.

As of your example, if I have two different subclasses if they implement the same interface at the end the interface will have one base method, one sub class method from first subclass and one sub method from the other class and basically making it unusable because it represents non existing objects (a mix of subclass 1 and subclass 2). This is not what is looked for in this case.

Oct 8, 2012 at 7:12 PM
Edited Oct 8, 2012 at 7:12 PM

Hello All, 

I Love this discussion and I was handling the problem myself on another topic ( here ) till someone pointed me to here.

I read all the point of view and indeed there is this issue where the compiler does not understand the "context".

Btw, the problem is actually deeper. Improving the compiler to understand the context would not match the following case scenario:

  • Module declaration to be used with an external, not written in TS, library

Indeed, consider this snippet ( Note the declare keyword ) : 

 

declare module lime {
	
	export class Node {
		private customEvent_;
		private eventHandlers_;
		inTree_: Boolean;
		supportedRenderers: any[];

		setAnchorPoint(x:number, y:number):Node;
		setPosition(x:number, y:number): Node;

		setOpacity(x:number): Node;

		appendChild(child:lime.Node, opt_pos?:number): Node;
		runAction(action:lime.animation.Animation):void;

	}
	
	export class Scene extends lime.Node {
		constructor();
		getScene(): Scene;
		measureContents(): void;
	}
}

 

 

This is, indeed, a snippet of a lime.d.ts file which aims to be a declaration file ready to be used with lime.js . As you probably already see the lime.Scene class extends lime.Node which contains a couple of methods which are there just for chainability.

So, as already said a lot of times in this topic the following code will work:

var tmp = new lime.Scene();
tmp.getScene().setPosition(0,0);

while the following won't:

var tmp = new lime.Scene();
tmp.setPosition(0,0).getScene();

But, in this example, where the source code is just a declaration, there's no way for the compiler to understand what the method will return since the declaration file will contain only the class/method signature.

So I'd like more the reserved keyword idea so that refactoring the code Above with _this as return type will fix the problem:

 

declare module lime {
	
	export class Node {
		private customEvent_;
		private eventHandlers_;
		inTree_: Boolean;
		supportedRenderers: any[];

		setAnchorPoint(x:number, y:number): _this;
		setPosition(x:number, y:number): _this;

		setOpacity(x:number): _this;

		appendChild(child:lime.Node, opt_pos?:number): _this;
		runAction(action:lime.animation.Animation):void;

	}
	
	export class Scene extends lime.Node {
		constructor();
		getScene(): Scene;
		measureContents(): void;
	}
}

Note that getScene method is not _this cause I don't want chainability to happen there.

Oct 8, 2012 at 8:07 PM

Using the _this modifier will imply that the compiler is able to perfectly understand the 'this' property in every possible call and I don't think this is working right now, at least I could not make it work in my tests.

I think this code clearly demonstrates that:

 

class A {
  public age: number = 0;
  constructor(public name:string){

  }
  setAge(age: number) {
    this.age = age;
    return this;
  }
}

class B extends A {
  constructor(name: string, age: number, profession: string) {
    super(name);
    this.setAge(age).setProfession(profession);

  }
  setProfession(occ: string) {
    this.occupation = occ;
    return this;
  }
}

 

Annotations aside, we have 2 keywords that in other cases has been provden for the compiler to understand: 'return' (it is able to find the types of return, for example if you declare a function to return number but you write the implementation as return ''; it will complain) and 'this' - it is used to check if the method name after that is actually present so if you write in a method this.nonExisting it will complain again. All this means that the compiler simply has to be able to determine correclty the type of the returned value and it does. Partially. In the above code I did not have to say that the call to 'setAge' returns 'A', compiler was able to figure out that on its own, however because the method was called from a subclass it should have casted automatically to B, because this is how it works in javascript: it knows what 'this' is on method call. The compiler however seem to 'forgets' it. This need to be fixed clearly, otherwise no chainable apis in subclasses will work, with or without _this. To make it clear: no need for special '_this' modifier, the compiler understands that 'this' is returned, it simply mistakes what is 'this'.

Oct 8, 2012 at 9:28 PM

@vekexasia

We are on the same boat. I got the problem with my streams API (https://github.com/Sage/streamlinejs/blob/master/lib/streams/server/streams.md). The ReadableStream/WritableStream classes define chaining methods that get inherited from the other classes of the module.

@pstj

If you have a method that returns "this" in a base class, you cannot infer that this method will *always* return this because the method may be overriden in a derived class to return something else. Consider the following:

class Base {
  m() { return this; }; 
}

class Derived1 extends Base {
  m1() { };
}

class Derived2 extends Base {
   m2() {};
}

class Derived3 extends Derived1 {
  m() { return new Derived2(); }
}

function foo(d1: Derived1, d2: Derived2) {
  d1.m1();
  d1.m().m1(); // rejected
}

The compiler is right when it rejects d1.m().m1() because d1 may be an instance of Derived3

So this is not a bug nor a limitation of the compiler. The compiler is OK but you have to give him a little hint to handle this case. If we could write:

class Base {
  m() : _this { return this; }; 
}

Then, in the example above, the compiler would reject the override of m() in Derived3 and it would accept d1.m().m1(). Precisely what we want for chaining!

Oct 8, 2012 at 11:22 PM
Edited Oct 8, 2012 at 11:24 PM

@bjouhier

glad to know i'm not alone :).

Btw i dislike your idea that the compiler would reject the override of any method marked for chainability. Consider, for example, a mock object that needs to be subclass of something and, obviously, needs to override almost any method. That restriction could cause a lot of problems.

Best solution ever (IMHO) is just mark the method with _this so that the compiler will know that the method will return the current object instance type ( not necessary the same instance ).

Consider the following: 

 

class LinkedList {
    value:any;
    nextNode: _this;
    public getNextNode(): _this {
         return this.nextNode;
    }
}

// Yeah i know it's a long name
interface DoubleLinkedListDataInterface {
       prev: DoubleLinkedList;
       next: DoubleLinkedList;
}

class DoubleLinkedList extends LinkedList{
    
    nodeData: DoubleLinkedListDataInterface;

    public getPrevNode(): _this {
          return this.nodeData.prev;
    }

    public getNextNode(): _this {
          return this.nodeData.next;
    }

   
}
var myList = new DoubleLinkedList(); myList.getNextNode().getPrevNode(); // this should work.

 

Also notice:

  • the _this keywrd as field type inside LinkedList => could come handy for another subclass which actually uses that field.
  • the override of the getPrevNode()
Oct 9, 2012 at 8:14 AM
bjouhier wrote:

@vekexasia

We are on the same boat. I got the problem with my streams API (https://github.com/Sage/streamlinejs/blob/master/lib/streams/server/streams.md). The ReadableStream/WritableStream classes define chaining methods that get inherited from the other classes of the module.

@pstj

If you have a method that returns "this" in a base class, you cannot infer that this method will *always* return this because the method may be overriden in a derived class to return something else. Consider the following:

 

class Base {
  m() { return this; }; 
}

class Derived1 extends Base {
  m1() { };
}

class Derived2 extends Base {
   m2() {};
}

class Derived3 extends Derived1 {
  m() { return new Derived2(); }
}

function foo(d1: Derived1, d2: Derived2) {
  d1.m1();
  d1.m().m1(); // rejected
}

 

The compiler is right when it rejects d1.m().m1() because d1 may be an instance of Derived3

So this is not a bug nor a limitation of the compiler. The compiler is OK but you have to give him a little hint to handle this case. If we could write:

class Base {
  m() : _this { return this; }; 
}

Then, in the example above, the compiler would reject the override of m() in Derived3 and it would accept d1.m().m1(). Precisely what we want for chaining!

Cannot agree with this. The compiler makes AST and is walking it (at least this is how is should work to be able to make all its checks). It is pretty obvious when a method is returning THIS and when a method is returning new Instance and it is also pretty clear what is the type of the instance it is returning, this is so natural I cannot believe we are still arguing about it!

last example and I am giving up:

 

class A {
  m1() {
    return this;
  }
}

class B extends A {
  m2() {
    return this;
  }
}

class SomethingElse {

}

class C extends B {
  m3() {
    return new SomethingElse();
  }
}

var instance = new C();
instance.m1().m2().m3().m1();

 

 

 

Here is how a compiler will work normally (and should work):

(starting from the initiation, I skip the code above but it is okay, because JS works tops down anyway, one can never make it read later lines first):

<Compiler at work - fiction by pstj>

I have an instance, what it is instance of? oh, okay it is a C, cool.

m1() -> a method call, cool, lets see if I have it defined on the class... nope, too bad, lets look at the prototype chain (aka the parent class)... next in chain is B, but it does not have it defined there... should check if it has something in the prototype chain... next in chain is A, lets see it I have it defined in A... Oh YEAH! I have it, lets see what does this method do.. hum, returns 'THIS', now what is this... lets look back to see what instance called it.. oh it is a C, great to the return is a C instance. Fine by me.., so the result of the call is instance of C, in fact it is the same instance!!! (this cannot be changed inside the method call, so it is safe to assume that is THIS is returned it is still the instance that called it.)

m2() -> hm... another method call, who is calling it - ah yeas, i remember, it is the C instance, lets see if I have it defined on C... no... ah, bad luck, check the parent... what is the parent of C, oh yeah, its B, check if B has it defined... yes it does, cool, what does it return... it return THIS, wohow, so my return type will be the calling instance, look back what it was - a C, so the return is instance of C!

m3() -> Again method call, a bit of a boring program... lets see if C has it defined.. ah it does! how great is that: now what is the return type.. hum.. a new instance of another class... okay then, mark a new instance of that class and remember that it is the value that is returned. great now the value I am working with is instance of SomethingElse (stupid name huh?)

m1() -> Ha, another method call, someone gotta be kidding me with those chained calls. Lets see do I have m1 defined on SomethingElse... nope. Does it have a parent. Nope. Ha! RAISE AN ERROR! Ha! How smart of a compiler I am....

 

So this is the tale of the brave compiler that knows what it is doing. Everything else with the '_this' is just plain fairy tales of the developer that went doing the compiler's job. 

 

Disclaimer: The narrative is only possible when one is compiling a whole program or when the class pattern in TypeScript is not abused. Why? Because of the dynamic type of the language one can go and simply override the method and lets say the instance is called by a function, which can also be called in another file:

 

function test() {
  (new C()).m1().m2().m3().m1();
}

 

And lets say in yet another file I have:

 

A.prototype.m1 = function() { return 'ha!'};

Now what will happen depends entirely on the order of the files. If one compiles only the the code that has the definitions and not the prototype method override, of course this will lead to errors. But let me ask this: even if you annotate that the method is returning _this and then again one goes and overrides the prototype "manually" and THEN the instance is created and methods chained, will the _this annotation help? I bet it will not. marking _this is simply a contract the developer makes with himself, not compiler directive. This is why it is pointless IMO, as long as the compiler can figure out the instance type of 'this' and it can, it is just a small bug IMO and it should be fixed. And of source if the compiler is compiling the whole application (i.e. --out) it should be able to figure out that m1 on A was overriden and return to the AST representation of it and override it and continue to the next line and from then on it will know that m1 returns). This  is how one can be sure, compiling the whole application together. Something that most JavaScript developers rarely use or even know.

 

Oct 9, 2012 at 8:51 AM

@pstj

I agree with you mainly for actual code. So that if the class is actually built in ts your ideas are ok. The problem comes when you want to create a declaration file where the implementation does not exists.

In this scenario ( see my previous post ) the compiler needs to get an help from the developer itself. Don't you agree?

Oct 9, 2012 at 4:03 PM

Hum... yes it is now much more clear what you might need this for. In that case the compiler cannot determine the correct type indeed.

So to clarify: _this might indeed be useful, but at least the compiler should be able to 'get it right' from actual implementation if provided.

Now that this is settled should someone file a bug/feature request?

Oct 9, 2012 at 9:10 PM

@pstj

Sorry but I continue to disagree with you. More precisely:

Your analysis of your example is right (did not read it through but I got the gist).

Your analysis of my example would be right if I had written the last lines as:

var d1 = new Derived1(); 
d1.m1();
d1.m().m1(); // rejected
But I wrote something different;

function foo(d1: Derived1, d2: Derived2) {
  d1.m1();
  d1.m().m1(); // rejected
}
The foo function may be called (from who knows where) as:

foo(new Derived3(), new Derived2());
This is perfectly valid because Derived3 extends Derived1

Then d1 is a Derived3 and the compiler is right to have rejected d1.m().m1() because d1.m() is a Derived2 !!!

When the compiler encounters a declaration like var s: string; it knows that s is *exactly* a string because string is a non-derivable type.

When it encounters a declaration like var d1 : Derived1, it only knows that d1 is an instance of Derived1 or of one of its subclasses. So it should not make inferences that assume that d1 is *exactly* a Derived1.

And if you push the analysis further, you will see that, if we introduce the _this type annotation on Base.m(), then the compiler has not much choice but reject the Derived3.m override that returns a Derived2 (Derived2 and Derived3 are different types).

Oct 10, 2012 at 7:16 AM

What you seem to not understand by not reading my explanation is that the compiler should threat method(): _this {} and method(): {return this} exactly the same.Anything beyond that is just waste of time that we argue here. Right now neither your preferred scenario nor mine work.

Mine is the correct behavior if the compiler is ever to pretend to understand a bit of class inheritance. Yours is not correct because you assume that the compiler does not know how (with what params) foo is called and if the compiler does not know (i.e. the code that invokes foo is not compiled together with the file providing foo) then the types do not matter at all. If the compiler is compiling the file invoking foo, it should be able to SEE that Direved3 m() method returns Derived2 and that in its inheritance chain is does not have m1(). Simple as that.

People should stop thinking of JS programs as independent pieces. This is what brought us to what we have today - a million libraries that all have different interfaces and do not work together and this is why it is so common to see in one and same page jquery (at least 2 versions of it of course), prototype and mootools.

If you think of all your code as 'one whole' and compile everything together the compiler will know exactly each type at each invocation. Right now even having all the code it cannot figure out what is what. Until that happens with or without _this special magical word, it is in internal alpha and should not be considered seriously by any one.

Oct 10, 2012 at 8:20 AM

You claim that the compiler should treat method(): _this {} and method():{ return this; } exactly the same BUT IT DOES NOT. Either it is a bug, or it is intentional. People from the compiler team should know. Can anyone from the MS compiler team comment?

You claim that this is a deficiency in the current compiler because the compiler should be able to know exactly each type at each invocation when compiling the source as a whole. This is wrong. Consider

class Base {}; class Derived1 extends Base {}; class Derived2 extends Base {}
function foo(b: Base) { } Math.random() % 2 ? foo(new Derived1()) : foo(new Derived2());

What is the exact type of b inside foo?

 

 

Oct 12, 2012 at 7:53 AM

You are right, I have researched this a little bit further (also asked about types of classes and method's type / params type in closure compiler forums). Turns out a subclass should be same or more permissive than the superclass. So if the return type of super class method is Base it is okay according to type system.

So the fact that it is possible in JavaScript to chain methods mixed from sub and super classes is well known but not possible from type system's perspective.

Having 'return this' is same as having method(): Base, then it is only natural that you would expect Base...

At this point I think that it is not clear how to express the possibilities of JavaScript in types when users want to use all javascript. In closure land it is not possible. I think it will never be possible in TypeScritp either.

Even if we mark the method with _this the example you have provided is defeating the type system because it simply cannot know at compile time what type will be submitted. So if one wants type check simply does not use code like this.

Oct 13, 2012 at 12:19 PM

Yes, subclass should be the same or more permissive than the superclass. This is what B. Meyer phrases as "subclassing is subcontracting" (when you subcontract you are supposed to fullfil at least all the terms of the original contract - rarely happens with building contractors :-( ).

This is also why returning new Derived2() in Derived3.m() in my previous example should be rejected by the compiler (because m() is annotated as returning _this).

I don't understand your last sentence. If we add a _this annotation to m() in the base class, we tell the compiler that m() and all its overrides (per the above rule) return the same type as this. Then the compiler can infer that d1.m() has the same type as d1 and can continue its type checking along the chain, and for example, find out that d1.m().m1() is ok but d1.m().m2() is not.

 

 

Oct 13, 2012 at 6:18 PM

True. But then you provide an example in which the run time determines the type of the param

In that case I belive no compiler for JS currently existing can determine the type of the result of m(), unless it is casted as it is now (to the base type) In which case no methods defined on the subclass will be allowed

example:

class Base { m(): _this {}}
class A extends Base {ma(): _this{}}
class B extends Base {mb(): _this{}}

var instance = (RANDOM?new A():new B());
instance.m().mb();

In this example what should the compiler say about the mb() part? I think the most sane thing is to say that _this is the base type (it is doing that right now so no need for _this annotation). What do you think?

Oct 13, 2012 at 6:45 PM

In this example the compiler should infer that instance is a Base (common ancestor of A and B). Then it can infer that instance.m() is a Base (which means that it could also be a A or B but we don't know which one). And then it rejects the mb() method because Base does not define it. This is not a problem, rather a feature.

What's nice on the other hand is that chaining APIs get correctly type checked. If you know that a is an A, the compiler accepts a.ma().m().ma() but rejects a.ma().m().mb(). And this works even if A has subclasses like A1, A2, etc. and if a is not exactly an A but an A1 or A2 (and we don't really know which one at the point where a is defined).

Oct 14, 2012 at 5:18 AM

You can solve this now without compiler support by giving it a little hint:

class Base {
  m() { return this }; // returns this for chaining
}

class Derived1 extends Base {
  m: () => Derived1;
  m1() { return this } // returns this for chaining
}

class Derived2 extends Base {
  m: () => Derived2;
  m2() { return this } // returns this for chaining
}

function foo(d1: Derived1, d2: Derived2) {
  d1.m1().m1().m(); // works
  d2.m2().m2().m(); // works
  d1.m().m1(); // works
  d2.m().m2(); // works
}
It is little tedious, but it works, and doesn't require redefining m().

Oct 14, 2012 at 12:21 PM

@ian320

Not ideal (you have to redeclare all chaining methods in all subclasses) but will do for now. Thanks for the tip.

Jul 1, 2014 at 3:03 PM
Edited Jul 1, 2014 at 3:04 PM
I've found a solution which may be more palatable for some. It using a generic base parameter similar to CRTP in C-PlusPlus. The trick to is to instantiate the instance using an interface parameter which self-extends the hierarchy. You then deal with instances of the interface in your code, rather than the concrete types.
class First<Base>
{
    one(): Base
    {
        return <Base><any>this;
    }
}


class Second<Base> extends First<Base>
{
    two(): Base
    {
        return <Base><any>this;
    }
}


interface ISecond extends Second<ISecond> 
{ 
}


var second: ISecond = new Second<ISecond>();

var two = second.one().two();