Reputation: 316
I have a base class and one or more sub classes that extend from it. I'm trying to implement the ability to create HTML elements easily.
My first class is the base class that contains common methods for all HTML elements:
class $NewElement<E extends HTMLElement> {
public element: E = null;
constructor(name: string) {
this.element = <E>document.createElement(name);
}
public className(className: string): any {
this.element.className = className;
return this;
}
}
I have other classes, each of which extends the above class. For example, this is the one for an img tag:
class $NewImage extends $NewElement<HTMLImageElement> {
constructor() {
super('img');
}
public source(fileName: string): $NewImage {
this.element.src = fileName;
return this;
}
}
I want to do something like this, in a type-safe manner:
let img = new $NewImage().className('a').source('b').element;
How can it be done? After calling className(), I'm no longer dealing with a $NewImage object, but rather a $NewElement object, which doesn't have the source() method.
Upvotes: 2
Views: 304
Reputation: 249606
You can use this
as a type, meaning the return type is the same as the type this method was invoked on:
class $NewElement<E extends HTMLElement> {
public element: E;
constructor(name: string) {
this.element = <E>document.createElement(name);
}
public className(className: string): this {
this.element.className = className;
return this;
}
}
class $NewImage extends $NewElement<HTMLImageElement> {
constructor() {
super('img');
}
public source(fileName: string): this {
this.element.src = fileName;
return this;
}
}
let img = new $NewImage().className('a').source('b').element; //works
Upvotes: 3