Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 288
John_911 Avatar asked Jan 27 '23 02:01

John_911


1 Answers

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('===============');
}
like image 132
Shaun Luttin Avatar answered Jan 31 '23 23:01

Shaun Luttin