升级到Knockout.js 3.5.0后,无法将“计算”分配给“可观察”

时间:2019-03-20 09:40:39

标签: typescript knockout.js

Knockout.js 3.5.0在npm上带有它自己的类型定义。 让我们将此变量x定义为:

const x: ko.Observable<boolean> = ko.computed(() => true);

现在我们得到了编译器错误: “计算类型”缺少“可观察”类型的以下属性:valueHasMutated,valueWillMutate

我了解编译器试图告诉我的内容,但是我认为原则上这是错误的-因为每个计算出的值也是可观察的。使用@ types / knockout中的类型定义,此行为在3.4.x上效果很好。

有一种Subscribable类型,我相信是某种“父”类型,它可以在声明中起作用:

const x: ko.Subscribable<boolean> = ko.computed(() => true);

这不会引发任何错误。但是,不会在值设置器上执行类型检查:

x(2);    // this is wrong but no compiler error

任何人都可以对这些新的类型层次结构更改有所了解吗?我们应该如何使用它?

4 个答案:

答案 0 :(得分:1)

在Knockout 3.5.1中,我能够引用Knockout软件包中定义的接口PureComputed

import * as ko from 'knockout';
import { Computed, PureComputed, Observable } from 'knockout';

class MyClass
  originalComments: string;
  comments: Observable<string>;

  constructor(serverData: any) {
    this.originalComments = serverData.comments || '';
    this.comments = ko.observable(this.originalComments);
  }

  hasChanged: PureComputed<boolean> = ko.pureComputed(() => this.comments() !==  this.originalComments);
}

答案 1 :(得分:0)

您可以像这样使用KnockoutComputed<T>

const x: KnockoutComputed<boolean> = ko.computed(() => true);

答案 2 :(得分:0)

或者,您可以添加编译器选项

"path" {
   ...
   "knockout": [ "node_modules/@types/knockout" ],
   ...
}

那样,您可以使用旧的KO类型,直到找到更好的升级代码的方式

答案 3 :(得分:0)

我现在正在自己升级到3.5.0。这是一个很大的更改,因为我们应该使用项目随附的类型文件,并且更改所有类的名称并摆脱全局ko。我认为这些都是好东西。我对代码的转换感到很满意(好吧,除了试图进行敲除验证进行编译之外)。

我遇到了您遇到的确切问题。我知道,当我将计算值分配给一个可观察的类型变量时,它就是一个hack,但是我也知道,因为接口足够紧密,它可以正常工作。这次升级迫使我重新审查了该hack,并对其进行了正确处理。现在,我在代码中执行以下操作:

我知道将变量定义为可观察变量或计算变量:

class SomeClass {
   public value: Observable<boolean> | Computed<boolean>;
}

这使所有可能正在阅读代码的其他开发人员都知道该值可能是计算值,因此他们不应只是盲目地为其分配值。