I want to make a TypeScript class that is loosely MyKOArray<T> extends KnockoutObservableArray<T>. Is this even possible? If so, is there a compact way to do it?
- I read Knockout's extenders section, but it doesn't seem applicable as I'm trying to (among other things) add a
stateattribute -- not affect the existing subscribable. - I could list the things I've tried and the ways they've gone wrong (e.g. TS2507, TS2322, etc.) but I doubt they'd be informative. As a baseline, I believe some of the essential details are:
KnockoutObservableArrayis an interface so I really need to "extend"ko.observableArray(the "factory" function).- The signature of
ko.observableArrayis not right (i.e. nonewand it handles the initial value in the function rather than aconstructormethod). - I could
return ko.observableArray(initial)from a constructor, but have not been able to get the prototype chain right (e.g. methods not available). - I could override
@@createin JS toreturn ko.observableArray(initial), but I've had trouble finding a JS example (let alone a valid TS implementation).
- I also found an extremely old discussion on a similar topic. The conclusion there was that it was impossible due to a lack of prototyping in KO, but the current source code (e.g.
ko.utils.setPrototypeOfOrExtend) suggests that this conclusion may be out-of-date. - I've also dug through plenty of generic TS extends questions (e.g. Can you extend a function in TypeScript?) without finding something that seemed to match.
===
EDIT: Why?
I'm attempting to decouple my system using the following pattern (only documenting the "interesting case"):
- ViewModel makes a request to a data service (indirectly via a factory method on a class). The data service returns an instance immediately (
MyClassorKnockoutObservableArray<MyClass>for a Singleton or Collection respectively). - Asynchronously, the service loads/populates (and manages real-time updates to) the returned instance. This requires a subscription to a WebSocket for events and REST call(s) to load data (incl. the potential for retries).
- The service passes its progress to the instance by calling methods on the instance (the "callback" and "errback" in my pattern).
- These methods update a
stateattribute (i.e. observable) and may update something else (e.g. populate its values or populate an error message observable). - The UI interrogates the
stateobservable to communicate the state of loading (and other activities) to the user.
This is working great on my single instances. The state method is interrogated (and updated) widely to ensure valid actions.
I'd like to duplicate the pattern on my KOArrays. That way, I can discriminate between an empty array that is not-yet-loaded and a loaded array that happens to be empty. I can also add a state and error_message to the KOArray to mirror the behavior of my instances.