Blog Details
Ayatullah Khameni
27 Oct 2024
2 min read
Method overloading is a powerful feature in TypeScript that allows a single method to have multiple signatures. This enables us to define different ways of calling a method based on the number or types of arguments. Today, we'll explore this concept using a real-world example from the NestJS framework: the `HttpException` class.
Let's look at the `createBody` method from the `HttpException` class:
class HttpException {
// ... other parts of the class ...
public static createBody(
nil: null | '',
message: HttpExceptionBodyMessage,
statusCode: number,
): HttpExceptionBody;
public static createBody(
message: HttpExceptionBodyMessage,
error: string,
statusCode: number,
): HttpExceptionBody;
public static createBody<Body extends Record<string, unknown>>(
custom: Body,
): Body;
public static createBody<Body extends Record<string, unknown>>(
arg0: null | HttpExceptionBodyMessage | Body,
arg1?: HttpExceptionBodyMessage | string,
statusCode?: number,
): HttpExceptionBody | Body {
if (!arg0) {
return {
message: arg1,
statusCode: statusCode,
};
}
if (isString(arg0) || Array.isArray(arg0)) {
return {
message: arg0,
error: arg1 as string,
statusCode: statusCode,
};
}
return arg0;
}
}
Breaking Down the Overloads
1. First Overload:
createBody(nil: null | '', message: HttpExceptionBodyMessage, statusCode: number): HttpExceptionBody;
This overload is used when you want to create a body with just a message and status code, without an error string.
2. Second Overload:
createBody(message: HttpExceptionBodyMessage, error: string, statusCode: number): HttpExceptionBody;
This overload allows creating a body with a message, an error string, and a status code.
3. Third Overload:
createBody<Body extends Record<string, unknown>>(custom: Body): Body;
This overload enables passing a custom body object, providing maximum flexibility.
4. Implementation:
createBody<Body extends Record<string, unknown>>(
arg0: null | HttpExceptionBodyMessage | Body,
arg1?: HttpExceptionBodyMessage | string,
statusCode?: number,
): HttpExceptionBody | Body
This is the actual implementation that handles all the above cases.
The TypeScript compiler uses these overloads to determine the correct method signature based on the arguments provided when calling `createBody`. The implementation then uses type checking to construct the appropriate response body.
Usage Examples:
// Using the first overload
HttpException.createBody(null, "Not Found", 404);
// Result: { message: "Not Found", statusCode: 404 }
// Using the second overload
HttpException.createBody("Forbidden", "Access Denied", 403);
// Result: { message: "Forbidden", error: "Access Denied", statusCode: 403 }
// Using the third overload
HttpException.createBody({ custom: "error", code: 500 });
// Result: { custom: "error", code: 500 }
Flexibility: It allows a single method to handle different input scenarios.
Type Safety: TypeScript ensures that the correct types are used for each overload.
Code Reusability: A single implementation can handle multiple use cases.
Improved Readability: Overloads provide clear documentation of the different ways a method can be used.
Don’t worry, we don’t spam!