我有一个模型类,它管理一个内部属性_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
。错误是:
我正在使用 Typescript 2.4.0
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);
}
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句