John_911
John_911

Reputation: 1170

How to define method on 3rd party class using typescript?

I'm trying to extend a 3rd party class but am having trouble getting typescript to play nice. Basically, I can't use any existing method already defined in the class in my new method.

A workaround would be to redefine existing methods in extensions.ts (see below), but there just has to be a better way.

3rd party index.d.ts

export as namespace thirdParty;

export Class SomeClass {
  // some methods here
}

My extensions.ts

import {thirdParty} from 'thirdParty'

declare module 'thirdParty' {
    namespace thirdParty {
        class SomeClass{
            newMethod(): this

            // works if I redfine the method here
            originalExistingMethod(): number
        }
    }
}

thirdParty.SomeClass.prototype.newMethod = function() {
    return this.originalExistingMethod() + 1
}

When calling an existing method like this.originalExistingMethod() above, typescript complains:

TS2339: Property 'originalExistingMethod' does not exist on type 'SomeClass'

Is there a way to avoid having to redefine existing methods when performing module augmentation?

Upvotes: 5

Views: 3673

Answers (1)

Shaun Luttin
Shaun Luttin

Reputation: 141462

Initial Answer

Here is an example using the Tensorflow library.

extend.ts

import { AdadeltaOptimizer } from '@tensorflow/tfjs-core';

declare module '@tensorflow/tfjs-core' {
    interface AdadeltaOptimizer {
        newMethod(message: string): void;
    }
}

AdadeltaOptimizer.prototype.newMethod = function (message: string) {
    console.log('===============');
    console.log(message);
    console.log('===============');
}

index.ts

import { AdadeltaOptimizer } from '@tensorflow/tfjs';
import "./extend";

const optimizer = new AdadeltaOptimizer(10, 10);

// the existing method is present
const className = optimizer.getClassName();

// the augmentation is also present
optimizer.newMethod(`The className is ${className}.`);

There is a similar example in the official TypeScript documentation, which augments Observable with a map method.

Follow Up on Comments

Thanks. Though my issue is using existing methods when defining newMethod. So in extend.ts not in index.ts. Any ideas on this?

This also works in extend.ts as follows:

import { AdadeltaOptimizer } from '@tensorflow/tfjs-core';

declare module '@tensorflow/tfjs-core' {
    interface AdadeltaOptimizer {
        newMethod(message: string): void;
    }
}

AdadeltaOptimizer.prototype.newMethod = function (message: string) {

    // just access the original method on `this` 
    const className = this.getClassName();

    console.log('===============');
    console.log(className);
    console.log(message);
    console.log('===============');
}

Upvotes: 7

Related Questions