我经常发现自己在地图模式中跟踪此缓存一些对象:
myMap = new Map<string, MyThing>;
getThing(key: string): MyThing {
let thing = this.myMap.get(key);
if (thing !== undefined) return thing;
thing = new MyThing();
this.myMap.set(key, thing);
return thing;
}
我想将其概括为:
getOrCreate(this.myMap, key, MyThing);
或
this.myMap.getOrCreate(key, MyThing);
初步实施理念:
export function getOrCreate<K, V>(map: Map<K, V>, key: K, objConstructor: () => V) {
let v = map.get(key);
if (v !== undefined) return v;
v = objConstructor();
map.set(key, v);
return v;
}
我是在重新发明轮子吗? TypeScript或ES6库是否已经有类似的东西? (我在Map中没有看到这种方法)
此外,我希望能够传递一般函数或对象构造函数
如何确定是否需要执行new objConstructor()
或objConstructor()
?
如果函数支持两者,objConstructor类型会是什么?
() => V | Constructor???() => V
或者我应该传递MyThing.constructor
作为论据;将调用等同于new MyThing()
?
或者只是if (objConstructor.constructor) new objConstructor();
?
通过定义Map.prototype.getOrCreate
?
如果我要修改Map.prototype,是否会影响使用原生{}
而不是new Map()
创建的地图,还是会影响另一种地图?
编辑:使用通用签名传递构造函数的问题。
getOrCreate(myMap, key, AsyncSubject);
AsyncSubject&#39;类型&#39;类型的参数不能分配给&#39;()=&gt;类型的参数AsyncSubject&#39;
您无法AsyncSubject<MyThing>
,这是语法错误。
AsyncSubject as any
有效,但有没有办法修复getOrCreate签名并维护类型检查?
此实现传递类型检查:
export function getOrCreate<K, V>(map: Map<K, V>, key: K, constructor: ( () => V ) | Object) {
let v = map.get(key);
if (v !== undefined) return v;
if (constructor instanceof Object) v = new (<any>constructor)();
else v = constructor();
map.set(key, v);
return v;
}
使用对象作为这种良好做法的类型吗?
当然() => new AsyncSubject<MyThing>()
有效,但这很详细。
TypeScript 2.0.3