A fluent interface designates an object-oriented API relying on method chaining to improve code readability. In such interfaces, methods return the object `this` to allow the caller to chain multiple method invocations. [source,javascript] ---- class RichText { constructor(private readonly text: string) {} bold(): RichText { // [...] return this; } italic(): RichText { // [...] return this; } } const richText = new RichText('Hello, World!'); // Chaining methods bold() and italic(). console.log(richText.bold().italic()); ---- To better support fluent interfaces when used with a hierarchy of classes, TypeScript provides a special type `this` that refers dynamically to the type of the current class. Methods returning `this` should thus use the corresponding special type `this` instead of the class name in their signatures. == Why is this an issue? When a method return type is the declaring class name in a hierarchy of classes, it is impossible to chain methods defined in the superclass with methods defined in subclasses. [source,javascript] ---- enum Color { RED, BLUE, GREEN } class Shape { // The return type is the class name. move(x: number, y: number): Shape { // [...] return this; } } class Polygon extends Shape { fill(color: Color): Polygon { // [...] return this; } } const polygon = new Polygon(); polygon.move(1.0, 2.0).fill(Color.RED); // ^^^^ // Property 'fill' does not exist on type 'Shape'. ---- == How to fix it When a method declaration uses the special type `this` instead of the class name for its return type, TypeScript will use the type of the object `this` instead of the method declaring class and will accept to invoke methods defined in the object class: [source,javascript] ---- enum Color { RED, BLUE, GREEN } class Shape { // The return type is now "this" move(x: number, y: number): this { // [...] return this; } } class Polygon extends Shape { fill(color: Color): this { // [...] return this; } } const polygon = new Polygon(); polygon.move(1.0, 2.0).fill(Color.RED); // No compilation error ---- === Code examples ==== Noncompliant code example [source,javascript,diff-id=1,diff-type=noncompliant] ---- class A { foo(): A { // Noncompliant return this; } bar = (): A => { // Noncompliant return this; }; } ---- ==== Compliant solution [source,javascript,diff-id=1,diff-type=compliant] ---- class A { foo(): this { return this; } bar = (): this => { return this; }; } ---- == Resources === Documentation * https://www.typescriptlang.org/docs/handbook/2/classes.html#this-types[this Types] * https://en.wikipedia.org/wiki/Fluent_interface[Fluent interface]