KnockoutJS& TypeScript(DefinitelyTyped):向Observables添加属性

时间:2016-02-18 14:35:25

标签: knockout.js typescript knockout-3.0 typescript1.6 definitelytyped

在KnockoutJS中,您可以向observableArrays添加其他属性,例如:

class Table {

    items: KnockoutObservableArray<SomeType>;

    constructor() {
        this.items = ko.observableArray<SomeType>();
        this.items.someMethod = ko.pureComputed([...]);
    }
}

也就是说,TypeScript会将someMethod属性标记为错误,不会编译。

以上内容似乎适用于KnockoutObservable<T>,但不适用于KnockoutObservableArray<T>(使用DefinitelyTyped的Knockout定义文件)。

有没有办法允许这些额外的属性而不必为每一个属性使用以下属性?

/// 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...
}

我也不热衷于将any用于父属性的定义。

修改

好的,似乎为了使其工作,需要使用索引器选项,然后将动态属性引用为this.items['someMethod']()而不是this.items.someMethod()。看起来TypeScript规范不允许在类定义中使用 dynamic 或任意属性。

1 个答案:

答案 0 :(得分:1)

如果要将任意属性附加到类型化对象,我发现这样做的最简单方法是在想要读取和写入这些属性时将对象强制转换为any。所以在你的情况下你会这样做:

 (self.items as any).someMethod = ko.pureComputed();
 var value = (self.items as any).someMethod();

此语法相当简洁,允许您访问任意属性,而不会丢失其他地方的常规类型保护。

话虽如此,我肯定会反对这种模式。向像这样的库对象添加任意属性只会使代码更难以阅读和推理,并没有真正提供任何好处。假设someMethod是某些特定于items的逻辑,我会将someMethod逻辑附加到父视图模型本身,或者如果有足够的逻辑与items相关,将该逻辑拉入其自己的viewmodel中,该viewmodel包含项目列表和相关逻辑。