dvlt
dvlt

Reputation: 41

typescript extend Array prototype

I just want to extend Array prototype with a method to convert each of the items of a sting array to uppercase, my first approach:

Array.prototype.toUppercase = () => {map(String.toUppercase);}

why is not working?

Thanks a lot!

Upvotes: 2

Views: 2933

Answers (1)

Aluan Haddad
Aluan Haddad

Reputation: 31803

You need to declare the member before you can implement it

interface Array<T> {
  toUpperCase(this: string[]): string[];
}

The implementation will look roughly like this

if (typeof Array.prototype.toUpperCase !== 'function') {
  Array.prototype.toUpperCase = function () {
    return this.map(c => c.toUpperCase());
  };
}

Note the check for an existing member is sort of sloppy. Just because it is a function doesn't mean it has the same behavior as what we would otherwise place there. Augmenting builtin prototypes should usually be avoided but sometimes it is useful. Never do this in a library and be warned that your code could break in some future environment.

Running example

We can see that TypeScript will raise an error if we call this on arrays of the wrong type

[1, 2, 3].toUpperCase(); // Error

['a,', 'b', 'c'].toUpperCase(); // OK

Note that if you are in a module context, you would wrap the declaration portion in a declare global block.

Putting it together:

// array-augmentations.ts

interface Array<T> {
  toUpperCase(this: string[]): string[];
}

if (typeof Array.prototype.toUpperCase !== 
'function') {
  Array.prototype.toUpperCase = function () {
    return this.map(c => c.toUpperCase());
  };
}

Upvotes: 7

Related Questions