The TypeScript ThisType<Type> utility type allows you to define the type of this within a specific object or function context, providing precise type checking for methods and properties accessed through this. The ThisType<Type> utility type is primarily used to provide type annotations for this context when defining function signatures or method signatures. It helps improve type checking and code intelligence in cases where TypeScript may not automatically infer the correct type.
Syntax
interface SomeInterface { someMethod(this: ThisType<SomeInterface>, ...parameters: any[]): ReturnType; }
Parameters
- SomeInterface: This represents the type (usually an interface) that defines the methods or functions.
- someMethod: This is the method or function within the interface that you want to define this context for.
- ThisType<SomeInterface>: This is where you use the ThisType utility type. It specifies that within someMethod, this context should be of type SomeInterface.
- parameters: any[]: These represent the parameters that the method or function takes.
ReturnType
This is the return type of the method or function
Example 1: In this example, we define a Printer interface for objects with a name property and a print method. Two printer objects, inkjetPrinter and laserPrinter, adhere to this interface. Their print methods access the name property to log messages with the printer’s name. TypeScript ensures the correct this context, enabling proper message printing for both printers. We have a Printer interface that represents printers with a name property and a print method. The print method expects this context to be of type Printer.
interface Printer { name: string;
print( this : ThisType<Printer>, message: string): void;
} const inkjetPrinter: Printer = { name: "Inkjet Printer" ,
print( this : Printer, message: string) {
console.log(`[${ this .name}] Printing: ${message}`);
},
}; const laserPrinter: Printer = { name: "Laser Printer" ,
print( this : Printer, message: string) {
console.log(`[${ this .name}] Printing: ${message}`);
},
}; // Outputs: [Inkjet Printer] Printing: Document 1 inkjetPrinter.print( "Document 1" );
// Outputs: [Laser Printer] Printing: Document 2 laserPrinter.print( "Document 2" );
|
Output
[Inkjet Printer] Printing: Document 1 [Laser Printer] Printing: Document 2
Example 2: In this example, we define an interface Shape with a name property and an area method. The circle object implements this interface, calculating its area based on the name and printing the result.
interface Shape { name: string;
area( this : Shape): number;
} const circle: Shape = { name: "Circle" ,
area( this : Shape): number {
if ( this .name === "Circle" ) {
// Compute and return the area of a circle
return Math.PI * Math.pow(2, 2);
} else {
// Return -1 for unsupported shapes
return -1;
}
},
}; console.log(`${circle.name} has an area of`+ ` ${circle.area()} square units.`);
|
Output
Circle has an area of 12.566370614359172 square units.
Reference: https://www.typescriptlang.org/docs/handbook/utility-types.html#thistypetype