In KnockoutJS, you can add additional properties to your observableArrays such as:
class Table {
items: KnockoutObservableArray<SomeType>;
constructor() {
this.items = ko.observableArray<SomeType>();
this.items.someMethod = ko.pureComputed([...]);
}
}
That said, TypeScript will mark the someMethod property as an error and won't compile.
It appears that the above works for KnockoutObservable<T>, but not for KnockoutObservableArray<T> (using DefinitelyTyped's Knockout definition files).
Is there a way to allow these additional properties without having to resort to the following for every single one?
/// Inside a custom definition file
interface KnockoutObservableArray<T> {
someMethod: any; // Works, but is tedious and pollutes the definitions
[x: string]: any; // Indexers don't work...
}
I am also not keen on using any for the parent property's definition.
Edit
Okay, it appears that, in order to get this to work, one needs to use the indexer option and then reference the dynamic property as this.items['someMethod']() rather than this.items.someMethod(). It looks like the TypeScript spec simply doesn't allow for dynamic or arbitrary properties in class definitions.
If you're going to attach arbitrary properties to typed objects, the easiest way I've found to do it is to cast the object to
anywhen you want to read and write those properties. So in your case you'd do:This syntax is fairly clean and lets you access arbitrary properties, without losing the general type protection elsewhere.
That being said, I'd definitely recommend against this pattern. Adding arbitrary properties to library objects like this just makes the code a bit more difficult to read and reason about and doesn't really provide any benefit. Assuming that
someMethodis some logic specific to theitems, I would either attach thesomeMethodlogic to the parent viewmodel itself, or if there is enough logic related toitems, pull that logic into its own viewmodel containing both the list of items and related logic.