V
V
Valery Chupurnov2017-07-21 00:32:08
JavaScript
Valery Chupurnov, 2017-07-21 00:32:08

How to extend class prototype in TypeScript after it's declared?

Good time. Help solve the problem:
There is a class

class Jodit {
 constructor(options) {}
}

the idea is that each instance of this class receives some custom settings when it is created. Which are added to the default ones. Previously, in jQuery plugins, I just extended 2 hashes - default and custom
class Jodit {
 static defaultOptions = {
     dog: 100,
     cat: 200
 };
 options: object
 constructor(options?: object) {
     this.options = extends(true, {}, Jodit.defaultOptions, options);
 }
}

let editor = new Jodit({
    dogs: 300
});

this approach has disadvantages: There is no auto-completion in the IDE, the editor stupidly does not know what we have in options, and TypeScript itself loses a lot of its predictability from this.
The second huge minus is the defaultOptions for the last project, huge. Just a sheet of hundreds of options. It turns out that for each instance of the class we duplicate this sheet, wasting the user's precious RAM.
Naturally, I decided to do this:
function Options() {
    
}
Options.prototype = {
    dog: 100,
    cat: 200
}
class Jodit {
 
 options: object
 constructor(options?: object) {
     let __options = new Options();
     this.options = extends(true, __options, options);
 }
}

the example works, the 2nd problem is solved. All settings are in a single instance, and only the necessary ones are overridden. But there is no auto-hinting here, the editor and TypeScript cannot be told what and where to take.
Second option:
class Options {
    dog = 100
    cat = 200    
}

class Jodit { 
 options: Options;
 constructor(options?: object) {
     let __options = new Options();
     this.options = extends(true, __options, options);
 }
}

problem 1 is solved, but now a full copy of all default properties will be created for each instance of Jodit. Even inheritance through a class does not solve the problem, because TypeScript transpiles inheritance into a complete copy of all properties.
Tell me how can I be, is it even possible?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
R
Ruslan Lopatin, 2017-07-21
@lorus

You can use generics:

interface Options {
    cats: number;
    dogs: number;
}

const defaultOptions: Options = { cats: 100, dogs: 100 };

class Jodit<O extends Options> {
    constructor(public options: O) {}
}

const jodit = new Jodit({ ...defaultOptions, mice: 1000 });

jodit.options.mice = 1024;

If you don’t want the options to be copied, then you will have to create classes for the options:
class Options {
    cats = 100;
    dogs = 100;
}

class Jodit<O extends Options> {
    constructor(public options: O) {}
}

class MiceOptions extends Options {
    mice = 1000;
}

const jodit = new Jodit(new MiceOptions());

jodit.options.mice = 1024;

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question