0

I have created a polyfill for the JavaScript Array;

if (Array.prototype.remove !== 'function') {
    Array.prototype.remove = function (value) {
        var idx = this.indexOf(value);
        if (idx !== -1) {
            return this.splice(idx, 1);
        }
        return false;
    };
}

Now I am upgrading the original JavaScript project to a TypeScript project and the tsc complains about the usage of the .remove method:

class Archive {
   documents: DocInfo[] = [];  // <-- Array of class DocInfo

   addDocument(document: DocInfo) {
      ...
   }

   deleteDocument(document: DocInfo) {
      this.documents.remove(document);
                     ^^^^^^
                     tsc complains here: TS2339:Property 'remove' does not exist on type 'DocInfo[]'
   }
}

How can I tell the tsc about this extension?

I tried creating a typings file, but without any success:

declare module 'Array' {
    export function removeByAttr(propertyName: string, propertyValue: any);
}

Thanks

4
  • Why not make it a part of DocType itself. Commented Nov 17, 2016 at 8:54
  • The remove method needs to be part of an "Array" of DocType. Not on DocType itself! Commented Nov 17, 2016 at 9:01
  • Moving it to Array.prototype will make it available for any type of array. Commented Nov 17, 2016 at 9:02
  • @Rajesh I already created the polyfill on Array.prototype, but that is in plain javascript. The tsc does not know about this. Commented Nov 17, 2016 at 9:11

2 Answers 2

1

The typings should extend Array<T> interface:

interface Array<T> {
    remove(item: T): boolean;
}
Sign up to request clarification or add additional context in comments.

5 Comments

Adding this code in a .d.ts file in my /typings folder did the trick!
Note, please suggest to use less generic name. This can have issues and might override original Array.remove function.
@Rajesh, Array has no remove function. And anyway the question is how to add typings.
Adding generic names in prototype is considered as bad practice because if its added in future, your code will override it. Also I just asked you to add this caveat
@AlekseyL. It will use native code, but overridden typing. that's a problem
1

Extending the Array class with an interface it's simple, you could try something like this:

Playground

    interface Array<T> {
   remove(o: T): Array<T>;
}

Array.prototype.remove = function (o) {

    var idx = this.indexOf(o);
        if (idx !== -1) {
            return this.splice(idx, 1);
        }
    return this;
}

class DocInfo { 
    name: string ;
    constructor(name) { 
        this.name = name;
    }
}

class Archive {
   documents: DocInfo[] = []; 
   addDocument(document: DocInfo) {
       this.documents.push(document);
   }
   deleteDocument(document: DocInfo) {
      this.documents.remove(document);
   }
   printDocuments() { 
       this.documents.forEach((item: DocInfo) => { 
           console.log(item.name);
       });

   }
}

const a = new Archive();
const _1 = new DocInfo('1');
const _2 = new DocInfo('2');

a.addDocument(_1);
a.addDocument(_2);
a.printDocuments();
a.deleteDocument(_1);
console.log('*********************');
a.printDocuments();
console.log('*********************');
a.addDocument(_1);
a.deleteDocument(_2);
a.printDocuments();

2 Comments

is there a way to make an array extension for only arrays that contain particular classes? ie. MyClass[] ?
@Gillardo sure with constraint, take a look at typescriptlang.org/docs/handbook/generics.html Using Type Parameters in Generic Constraints

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.