How to Extend Object.prototype in TypeScript


Borislav Hadzhiev

Last updated: Feb 26, 2022


Photo from Unsplash

Extend Object.prototype in TypeScript #

To extend Object.prototype in TypeScript:

  1. Create an object.extensions.ts file.
  2. Extend the Object interface and add the extension method.
  3. Import the extension method as import './object.extensions' before using it.

Here is the content of object.extensions.ts:

interface Object { // 👇️ function log - no parameters, returns object log(): Record<string, unknown>; } // 👇️ Don't use arrow function Object.prototype.log = function () { console.log(this); return this as Record<string, unknown>; };

And here is how we import and use the new log method on the Object prototype:

import './object.extensions'; const obj = { name: 'Tom', age: 30, }; obj.log();

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

object prototype extended

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

In the interface, we created a log method, which returns an object with string keys and unknown values.

The method simply logs the object and returns it.

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 Object.prototype with any method. Here is an example that implements a merge method that merges 2 objects.

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

interface Object { merge(obj: Record<string, unknown>): Record<string, unknown>; } Object.prototype.merge = function (obj: Record<string, unknown>) { return { ...this, ...obj }; };

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

import './object.extensions'; const obj = { name: 'Tom', age: 30, }; const merged = { country: 'Chile', city: 'Santiago' }.merge(obj); // 👇️ {country: 'Chile', city: 'Santiago', name: 'Tom', age: 30} console.log(merged);

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

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

Here is the original Object interface:

interface Object { constructor: Function; toString(): string; toLocaleString(): string; valueOf(): Object; hasOwnProperty(v: PropertyKey): boolean; isPrototypeOf(v: Object): boolean; propertyIsEnumerable(v: PropertyKey): boolean; }

For example, here is how you would override the built-in toString() method.

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

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

import './object.extensions'; const obj = { name: 'Tom', age: 30, }; console.log(obj.toString()); // 👉️ "hello"

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.