2

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!

dvlt
  • 41
  • 1
  • 3

1 Answers1

7

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());
  };
}
Aluan Haddad
  • 29,886
  • 8
  • 72
  • 84
  • I just want to add this method using console, I understand that i am missing the reference to the object and is why does not work. Still thinking about how to implement it. :( – dvlt Dec 01 '17 at 11:59
  • I don't know what you mean. TypeScript is just JavaScript. Adding the interface is for the checker and for documentation. If you are in browser console just paste the executable code (my version not yours) and run it. – Aluan Haddad Dec 01 '17 at 12:34