Declare (define) Class member methods
A bit late, but I had a similar requirement when converting parts of a legacy system to TypeScript, so this might help somebody else.
If you know your class will be enhanced at runtime with other methods and you simply want to have type information and intellisense available for those methods, AND you don't want to write ugly stubs, you can try this:
First, define your interface(s) detailing the runtime methods:
interface RuntimeImplementedType {
public method(): void;
}
interface AnotherRuntimeImplementedType {
public other_method(): void;
}
Then define a variable whose type is specified as a constructor function returning the union of the types that you want to inform TypeScript your class implements at runtime. Assign the variable a function returning an empty object literal, casting to "any" so as to avoid compiler grumbles and ensure that when transpiled, what is actually being extended is just a plain old empty object.
const Base: new() => RuntimeImplementedType & AnotherRuntimeImplementedType = (() => {}) as any;
Now define your new class, extending from your constructor function variable:
class Classic extends Base {
public doSomething() {
this.method();
this.other_method();
}
}
All methods from the interfaces should be available, but without having to actually provide an implementation.
Related videos on Youtube
Comments
-
Rudolf Gröhling almost 2 years
I have TypeScript ES6 Class, suppose it looks like this
class Classic private _member: Object; constructor(member: Object) { this._member = member; } }
And I have some rich object, that contains a lot of methods, which I want to inherit, but that object is not a TS or ES6 Class, it's just POJO (ObjectLiteral).
So I made quick and dirty inheritance like
Object.assign(Classic.prototype, ObjectLiteralWithMethods);
No need for deep copy, everything works.
How can I tell TypeScript that
Classic
has these inherited methods and specify their behavior?I searched for keywords like declare OR define AND class AND method, but my google-fu is not sufficient.
I tried define interface for
Classic
, but it did not work either.I tried to declare class like
declare class ObjectLiteralWithMethods { public method(): void; protected _method(parameter: string): void; }
and then extend that declaration like
class Classic extends ObjectLiteralWithMethods { ... }
but then TypeScript wants me to call
super()
inconstructor
, which fails.I know that I can implement "dummy" methods on
Classic
likeclass Classic { dummyMethodImplementation(param: string): string { return param; } }
but this would be painfull and inefficient. I just want to define/declare that class
Classic
is extended.SOLVED
Sort of...
The
ObjectLiteralWithMethods
in my case was actually a prototype for jQuery widget. So, I extended the owner of the prototype.It needed some patching, because TS was not aware of the owner so I made:
// declaring the properties and methods which will be inherited by my class declare class JQueryUIWidget { public property: string; public method(): string; ... } // must declare a constructor for JQueryUIWidget to be able to extend // and cast the value to any, so TS do not mind const Widget: { new (): JQueryUIWidget } = $.Widget as any; // and then extend that declaration class Classic extends Widget { constructor() { super(); // super(); is mandatory here, with plain object it // did not worked, but since Widget is in fact a Function // it works now } }