键入以将新项目推送到数组中

时间:2017-06-26 22:44:01

标签: typescript typescript2.0

我有一个模型类,它管理一个内部属性_record,它是数据库中的记录。模型类是通用基类,每个模型类型都扩展了这个基类。

我想提供两种方便的方法来修改记录中的属性: setValue 用于设置离散数据结构, pushValue 用于将离散数据结构推送到数组上。

/**
 * Allows setting individual properties on the record
 * 
 * @param key the property on the record you want to set
 * @param value the value of the property
 */
public setValue<K extends keyof T>(key: K, value: T[K]) {
  this._record[key] = value;
}

/**
 * Allows setting an individual property on a record where the property
 * must be an array and result of the operation is the addition 
 * of a new array element
 * 
 * @param key the property name on the model's record
 * @param value an element to add to the existing array
 */
public pushValue<K extends keyof T>(key: K, value: keyof T[K]) {
  if (!this._record[key]) {
    this._record[key] = [ value ] as T[K];
  } else if (Array.isArray(this._record[key])) {
    this._record[key] = this._record[key].concat(value);
  }
}

setValue工作正常,但我正在为pushValue的适当类型进行挣扎。错误是: error 1

error 2

  

我使用的是Typescript 2.4.0

1 个答案:

答案 0 :(得分:1)

Array.isArray(this._record[key])不能用作类型后卫,this._record[key]仍然在其后输入T[K],可能是因为索引属性访问(此处报告了类似问题:https://github.com/Microsoft/TypeScript/issues/11483 ,决议“因性能原因而被拒绝”。)

该问题的建议解决方法是将中间变量而不是this._record[key]传递给类型保护,它确实有效。对于一个简单变量,其类型推断为const v: T[K] & any[]any[]部分来自Array.isArray类型后卫,因此此代码使用--noImplicitAny编译:

abstract class Model<T> {

    _record: T;

    public setValue<K extends keyof T>(key: K, value: T[K]) {
        this._record[key] = value;
    }


    public pushValue<K extends keyof T, V>(key: K, value: V) {
        const v = this._record[key];
        if (!v) {
            this._record[key] = [value] as any;
        } else if (Array.isArray(v)) {
            v.push(value);
        }
    }

}