I normally add custom knockout binding handlers in JavaScript via
ko.bindingHandlers.myBindingHandler = {...}
but now I have to add them in TypeScript via
ko.bindingHandlers["myBindingHandler"] = {...}
otherwise I get this error because I'm using typescript.d.ts:
The property 'myBindingHandler' does not exist on value of type 'KnockoutBindingHandlers'
I don't like the ["property"]
approach because then I can't reference it or get intellisense on it later.
So, how can I add my custom binding handler to knockout while using definitelyTyped's knockout definition, while also being able to reference my definition via intellisense, etc?
A binding context is an object that holds data that you can reference from your bindings. While applying bindings, Knockout automatically creates and manages a hierarchy of binding contexts. The root level of the hierarchy refers to the viewModel parameter you supplied to ko. applyBindings(viewModel) .
Binding Values The binding value can be a single value, literal, a variable or can be a JavaScript expression.
Its actually pretty easy, just add it (myBindingHandler
) to the KnockoutBindingHandlers
interface right before you define your custom binding handler. Please note that you have to do make this addition to the interface, within a .d.ts
file as of version 1.0 (or possibly earlier).
bindingHandlers.d.ts
/// <reference path="typings/knockout/knockout.d.ts" /> interface KnockoutBindingHandlers { myBindingHandler: KnockoutBindingHandler; }
myBindingHandler.ts
/// <reference path="bindingHandler.d.ts" /> ko.bindingHandlers.myBindingHandler = {...}
Now everything works. This will not overwrite any existing definitions or declarations, so your definition will sit along side of ko.bindingHandlers.text
, etc.
Just be careful, because if you do not include an actual definition of myBindingHandler
and you reference it elsewhere, it will compile due to the definition you added to KnockoutBindingHandlers
, but it will break at runtime because there is no implementation of myBindingHandler
.
The documentation for adding custom bindinghandlers in knockoutjs is here
Similarly, to add something to ko.observable.fn
, you'd do this in typescript
interface KnockoutObservableFunctions { myFnExtension(args: any): returnType; }
and call it with
// x will be defined as a returnType automatically, but you could specify it if you like, either way var x: returnType = ko.observable("value").myFnExtension(args);
Note: There are different interfaces for the subscribable
, observable
, observableArray
, and computed
types:
ko.subscribable.fn
... add to KnockoutSubscribableFunctions
ko.observable.fn
... add to KnockoutObservableFunctions
ko.observableArray.fn
... add to KnockoutObservableArrayFunctions
ko.computed.fn
... add to KnockoutComputedFunctions
The documentation for adding onto fn in knockoutjs is here
you can simply ignore it,but this is not a good practice, by casting to any
you are not defining the type of the property myBindingHandler
(<any>ko.bindingHandlers).myBindingHandler = { ... };
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With