Master TypeScript Decorators by Building an Automated Retry Utility
Take a deep dive into Method Decorators. Step-by-step guide on creating a @Retry annotation to automatically re-invoke failed functions.

Master TypeScript Decorators by Building an Automated Retry Utility
H ey devs 👋
This blog is a continuity post for the custom decorator we explored last. While discussing the custom decorators with the team, they asked me to create a few, including one called retry.
Purpose of retry decorator
We are using promises to call the API and doing some async actions at the UI level. We have a use case where we retry the same API calls a few times and return the response. As usual, we know the decorator, so let's start with the custom decorator.
Not a Medium member? You can read the full article for free by clicking here. 🔗
Those who missed my previous blog, please read it.
Creating a file named retry.decorator.ts.
export function Retry(count: number) {
return function aync(
target: Object,
propertyKey: string | undefined,
descriptor: TypedPropertyDescriptor<any>,
) {
const originalMethod = descriptor.value;
descriptor.value = async function (...args: any[]) {
let lastError: any;
for (let i = 0; i < count; i++) {
try {
return await originalMethod.call(this, args);
} catch (error) {
lastError = error;
console.warn(`Attempt ${i + 1} failed. Retrying...`);
}
}
throw lastError;
};
return descriptor;
};
}
- Retry is a factory function defined to pass the count as a parameter (@Retry(3)).
- The inner function is what TypeScript calls to modify the class or method.
**target**: The class prototype.**propertyKey**: The name of the method being decorated (e.g callApi()).**descriptor**: An object containing the actual function logic.- Store the original function in a variable and then override it using a descriptor.value.
- Based on the count, the loop will be executed; if the promise achieves success, then it will be returned. If an error occurs, it will keep on retrying until the loop is completed. It will throw an error if it fails even though the loop has finished.
Implementation
@Retry(2)
async retryPromiseDecorator() {
if (!this.count) {
this.count++;
return Promise.reject('rejected promise');
} else {
return Promise.resolve('resolved success');
}
}
async callPromise() {
const data = await this.retryPromiseDecorator();
console.log(data);
}

Note: This specific code uses the Legacy (Experimental) API. If you are using TypeScript 5.0+ without
experimentalDecorators: true, the parameters (target,propertyKey,descriptor) would be replaced by a singleoriginalMethodand acontextobject.
Want to explore the code in detail or try it out locally? Check out the full working example on GitHub: 👉 Source Code: C**ustom-decorator**
Thanks for reading! If this was helpful, consider clapping 👏 and following for more full-stack tips. Do you have questions or suggestions? Drop them in the response below!
✍️ Author: **Vetriselvan Panneerselvam**
👨💻 Full Stack Developer | 💡 Code Enthusiast | 📚 Lifelong Learner | ✍️ Tech Blogger | 🌍 Freelance Developer
메타데이터
- post_id
- c64aed2fe3b2
- slug
- master-typescript-decorators-by-building-an-automated-retry-utility-c64aed2fe3b2
- url
- https://medium.com/@vetriselvan_11/master-typescript-decorators-by-building-an-automated-retry-utility-c64aed2fe3b2
- canonical_url
- https://medium.com/@vetriselvan_11/master-typescript-decorators-by-building-an-automated-retry-utility-c64aed2fe3b2
- author_url
- https://medium.com/@vetriselvan_11
- status
- ok
- fetched_at
- 2026-07-11 13:42:50