我应该如何为挖掘扩展器添加一个打字稿定义,为一个observable添加方法?

时间:2017-02-15 16:31:42

标签: typescript knockout.js observable

我有一个淘汰扩展器,我想在打字稿文件中使用,我无法弄清楚如何声明它。

扩展程序是用javascript编写的,我想从一个打字稿文件中使用它(因为该项目目前是javascript和typescript的混合)。但是,我还没有能够找到如何为扩展器添加定义。从this question我已添加到KnockoutExtenders界面(虽然我不确定我是否错过了该问题的重点),如下所示:

interface KnockoutExtenders {
    trackChange<T>(target: T, track: boolean): ITrackChange<T>;
}

interface ITrackChange<T> extends KnockoutObservable<T> {
    setOriginalValue(startingValue: T): void;
    resetToConfirmedValue(): void;
    setConfirmedValue(): void;
    numberChanges(): number;
}

扩展器的用法如下:

class ProductTypeViewModel {
    constructor() {
        this.name.setOriginalValue('Initial value');
    }

    name = ko.observable('').extend({
        trackChange: true
    });
}

我在this.name.setOriginalValue上遇到了一个打字稿构建错误,因为Property 'setOriginalValue' does not exist on type 'KnockoutObservable<string>',这当然是正确的。

我应该如何声明扩展器以便打字稿能够识别出已经给出了可观察的新方法(即它不再是KnockoutObservable<string>并且现在是ITrackChange<string>)?

(不确定扩展器的解释是否相关,但无论如何它都在这里: 扩展器跟踪可观察的变化并允许它们被接受/取消。这允许使用observable来显示当前值,并且在编辑模式上可以使用相同的observable来更改值,但是在用户确认他们在模态中的更改之前,基础值实际上不会改变。如果他们取消它们,实际上没有任何改变。)

2 个答案:

答案 0 :(得分:0)

尝试以下

interface KnockoutObservable<T> extends Observable<T> {
  setOriginalValue(param: string): void;
}

class ProductTypeViewModel {
    private name: KnockoutObservable<string>;

    constructor() {
        this.name.setOriginalValue('Initial value');
    }
}

答案 1 :(得分:0)

我已经能够通过手动转换observable的类型来解决typescript错误。

name = ko.observable('').extend({
    trackChange: true
}) as ITrackChange<string>;

我希望能够在某个地方注册它,这样我就不必在每个可观察的扩展上使用这个强制转换,但是手动完成它就足够了。如果有人想出更好的解决方案,我会高兴地接受他们的回答。 (如果这是一个糟糕的方法,请做出评论解释原因,我总是乐于学习!)

请注意,如果observable有多个扩展器,则可以使用交集类型来显示所有相关接口,如this answer to a different question所示:

name = ko.observable(false).extend({
    trackChange: true,
    logChange: true
}) as ITrackChange<boolean> & ILogChange<boolean>;