具有不确定属性的类

时间:2019-01-03 10:37:57

标签: typescript dynamic properties

我正在尝试构建一个类,该类将累积行和列的值,每个行/列由字符串标识。我希望该代码能提供足够的说明性:

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:字符串,nmCol:字符串,值:TYPE)的属性'fnset'   => void'不能分配给字符串索引类型'{[idCol:string]:TYPE; }'。ts(2411)

实现此目标的解决方法是什么?

1 个答案:

答案 0 :(得分:1)

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

最好的解决方案是不要使用实际的类来存储这些动态值。使用可以在字段中保存的单独的专用对象。这样可以避免意外覆盖类方法(例如,有人可以调用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(){

    }
}