1

This seems so trivial, yet I fail to make it work. I have a class Collection in an external npm dependency (say packagename). In my current project, I would like to add some methods to the prototype of that class, and informing TS of that fact.

In the external module, the class is defined like :

export class Collection<T extends Document> {
  // ...
}

So here is what I wrote in an external.d.ts file in my project :

import { Document } from "packagename";

declare module "packagename" {
  export interface Collection<T extends Document> {
    newMethod(): Promise<T | null>;
  }
}

But then in another file :

import { Collection } from "packagename"

Collection.prototype.newMethod= function<T extends Document>(this: Collection<T>) {
  // ...
};

fails with the following error :

TS2693: 'Collection' only refers to a type, but is being used as a value here.

Same goes if I import Collection with import * as everything from 'packagename' then everything.Collection.

What am I missing here ? Thanks.

2 Answers 2

2

So it seems that it doesn't work because imports from packagename are re-exported imports in a index.ts file that only aggregates other files. Targeting the exact source file of the class I wanted to augment seems to work :

import { Document } from "packagename";

declare module "packagename/dist/collection" {
  export interface Collection<T extends Document> {
    newMethod(): Promise<T | null>;
  }
}

This comment gave me the hint.

Sign up to request clarification or add additional context in comments.

Comments

0
  1. Typescript allows you to extend the interface (what you did), but the interface is just a type (no implementation as you see).

  2. I do not understand you need to extend the class in that way. Why don't you just create a child class based on the existing one? It seems like a right way to extend class instead of monkey patching via prototype extending

import { Collection } from "packagename"

export class ExtendedCollection extends Collection {
  newMethod() {

  }
}

and after that in places, you need just import and use that new class

do you have strong reasons to not do it in such a way?

1 Comment

Because then I wouldn't be able to use newMethod for example on a Collection returned by the external package (which is a type that I don't control). Module augmentation is supposed to work around that. Example : stackoverflow.com/a/61485387/11153160

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.