Как определить обработчик привязки нокаута в typescript?

Я обычно добавляю пользовательский нокаут привязки обработчиков в JavaScript через

ko.bindingHandlers.myBindingHandler = {...}

но теперь я должен добавить их в TypeScript через

ko.bindingHandlers["myBindingHandler"] = {...}

В противном случае я получаю эту ошибку, потому что я использую typescript.d.ts:

Свойство 'myBindingHandler' не существует при значении типа 'KnockoutBindingHandlers'

Мне не нравится подход ["property"], потому что тогда я не могу ссылаться на него или получить intellisense на нем позже.

Итак, как я могу добавить свой обработчик привязки к нокауту при использовании definitTyped определение нокаута, а также может ссылаться на мое определение через intellisense и т.д.?

Ответ 1

Определение специального обработчика привязки

На самом деле это довольно просто, просто добавьте его (myBindingHandler) в интерфейс KnockoutBindingHandlers прямо перед тем, как определить свой собственный обработчик привязки. Обратите внимание, что вам нужно сделать это дополнение к интерфейсу в файле .d.ts с версии 1.0 (или, возможно, ранее).

bindingHandlers.d.ts

/// <reference path="typings/knockout/knockout.d.ts" />

interface KnockoutBindingHandlers {
    myBindingHandler: KnockoutBindingHandler;
}

myBindingHandler.ts

/// <reference path="bindingHandler.d.ts" />

ko.bindingHandlers.myBindingHandler = {...}

Теперь все работает. Это не заменит никаких существующих определений или деклараций, поэтому ваше определение будет сидеть рядом с ko.bindingHandlers.text и т.д.

Просто будьте осторожны, потому что, если вы не укажете фактическое определение myBindingHandler и вы ссылаетесь на него в другом месте, оно будет скомпилировано из-за определения, которое вы добавили в KnockoutBindingHandlers, но оно сломается во время выполнения, потому что нет реализация myBindingHandler.

Документация по добавлению пользовательских дескрипторов привязки в knockoutjs здесь

Используя fn для добавления пользовательских функций с помощью TypeScript

Аналогично, чтобы добавить что-то в ko.observable.fn, вы сделали бы это в TypeScript

interface KnockoutObservableFunctions  { 
    myFnExtension(args: any): returnType; 
}

и назовите его

// 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);

Примечание. Существуют разные интерфейсы для типов subscribable, observable, observableArray и computed:

  • ko.subscribable.fn... добавить в KnockoutSubscribableFunctions
  • ko.observable.fn... добавить в KnockoutObservableFunctions
  • ko.observableArray.fn... добавить в KnockoutObservableArrayFunctions
  • ko.computed.fn... добавить в KnockoutComputedFunctions

Документация для добавления на fn в knockoutjs здесь

Ответ 2

вы можете просто игнорировать его, но это не очень хорошая практика, путем нажатия на any вы не определяете тип свойства myBindingHandler

(<any>ko.bindingHandlers).myBindingHandler = { ... };

Ответ 3

Другой грязный способ игнорировать любую проверку типов:

let bindingHandlers: any = ko.bindingHandlers;
bindingHandlers.myHandler = {...}