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

KnockoutJS & TypeScript (DefinitelyTyped): Adding Properties to Observables

在 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 或 class 定义中的任意属性。

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

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

此语法相当简洁,可让您访问任意属性,而不会丢失其他地方的一般类型保护。


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