首页 > 解决方案 > 具有未确定属性的类

问题描述

我正在尝试构建一个可以为行和列累积值的类,每行/列都由一个字符串标识。我希望代码足够说明:

class TMatrix<TYPE>{

    [idRow: string]: { [idCol: string]: TYPE };

    fnset(nmRow: string, nmCol: string, value: TYPE ) {
      if (!this[nmRow]) 
          this[nmRow] = {};
      this[nmRow][nmCol] = value;
    }

    buildHtmlTable(){
    ...
    }
}

事实上,上面的代码有效,但打字稿在方法中抱怨:

'(nmRow: string, nmCol: string, value: TYPE) => void' 类型的属性 'fnset' 不可分配给字符串索引类型 '{ [idCol: string]: TYPE; }'.ts(2411)

什么可能是解决方法或实现此目的的正确方法?

标签: typescriptdynamicproperties

解决方案


索引签名必须与该类型的所有成员兼容。这包括类的方法。

最好的解决方案是不使用实际类来存储这些动态值。使用您可以在字段中保存的单独的专用对象。这避免了类方法的意外覆盖(fnset('fnset', '', 0)例如,有人可以调用和覆盖 `fnset 方法)

class TMatrix<TYPE>{

    data: { [idRow: string]: { [idCol: string]: TYPE } } = {};

    fnset(nmRow: string, nmCol: string, value: TYPE ) {
    if (!this.data[nmRow]) 
        this.data[nmRow] = {};
    this.data[nmRow][nmCol] = value;
    }

    buildHtmlTable(){

    }
}

如果您真的想将数据保留在类中,则需要使索引签名与所有成员兼容:

class TMatrix<TYPE>{

    [idRow: string]: { [idCol: string]: TYPE } | TMatrix<TYPE>[keyof TMatrix<TYPE>]

    fnset(nmRow: string, nmCol: string, value: TYPE) {
        const data = this[nmRow];
        if (!data) {
            this[nmRow] = data;
        }
        if (typeof data === 'function') { // gurad agains overriding memebers, depeding on class memebers this may have to change to exclude other members, this works if you only have extra methods, no other fields
            throw  "don't override methods"
        }
        data[nmCol] = value
    }

    buildHtmlTable(){

    }
}

推荐阅读