How to Extend Number.prototype in TypeScript


Borislav Hadzhiev

Last updated: Feb 26, 2022


Photo from Unsplash

Extend Number.prototype in TypeScript #

To extend Number.prototype in TypeScript:

  1. Create a number.extensions.ts file.
  2. Extend the Number interface and add the extension method.
  3. Import the extension method as import './number.extensions' before using it.

Here is the content of number.extensions.ts:

interface Number { sum(a: number): number; } Number.prototype.sum = function (a: number) { return Number(this) + a; };

And here is how we import and use the new sum method on the Number prototype:

import './number.extensions'; const num = 100; console.log(num.sum(5000)); // 👉️ 5100

If I run my index.ts file, we can see that the sum method gets successfully invoked.

number prototype extended

We declared a new interface Number, which will get merged with the original Number interface.

In the interface, we created a sum method, which adds 2 numbers and returns the result.

Make sure to use a named function when extending the prototype, and not an arrow function, because arrow functions use the this of the enclosing scope, which is not what you want.

You could use this approach to extend Number.prototype with any method. Here is an example of a method that adds leading zeros to a number.

This is the code in the number.extensions.ts file:

interface Number { addLeadingZeros(): string; } Number.prototype.addLeadingZeros = function () { return padToDigits(Number(this), 5); }; function padToDigits(num: number, totalLength: number) { return num.toString().padStart(totalLength, '0'); }

And here is the index.ts file, which imports number.extensions and makes use of the addLeadingZeros method.

import './number.extensions'; const num = 100; // 👇️ "00100" console.log(num.addLeadingZeros());

Make sure to specify the correct path when importing the number.extensions.ts module.

When overriding Number.prototype, make sure your methods are not interfering with built-in method names, unless intentionally overriding them (which can be confusing).

This is how the original Number interface looks like:

interface Number { toString(radix?: number): string; toFixed(fractionDigits?: number): string; toExponential(fractionDigits?: number): string; toPrecision(precision?: number): string; valueOf(): number; }

Here is an example of how you would override the built-in toString() method.

interface Number { toString(): string; } Number.prototype.toString = function () { return 'hello world'; };

And here is the code in our index.ts file.

import './number.extensions'; const num = 100; // 👇️ "hello world" console.log(num.toString());

Note that overriding built-in methods is confusing and should generally be avoided.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.