我是Angular / TS的新用户,并且喜欢使用Extension方法。他们在标准类型上做得很好,但是现在我正在尝试为Map编写一个其中V将被数组化的模型,但是不幸的是它似乎不起作用。
我要尝试的是,该扩展方法会将地图V初始化为数组,然后推送值或如果已经初始化则推送。
declare global {
interface Map<TKey, TValue[]>
{
SetInArray(key:TKey, value:TValue):boolean;
}
}
Map.prototype.SetInArray = function<TKey, TValue>(key:TKey, value:TValue):boolean {
let isNew:boolean = false;
if(this.has(key) == false){
this.set(key, []);
isNew = true;
}
let items:TValue[] = this.get(key);
items.push(value);
return isNew;
};
export {};
请告知
谢谢
答案 0 :(得分:4)
存在一些问题(除了普遍的知识是you should not extend native object prototypes之外)。第一个是声明通用接口或类型时,其类型参数必须是裸名,而不是其他类型的函数。所以你不能拥有
interface Foo<T, U[]> {} // error
如果要求第二个类型参数为数组,则应使用generic constraint:
interface Foo<T, U extends any[]> {} // okay
下一个问题是,如果以任何方式更改类型参数或其约束,则无法merge declarations。 Map<K, V>
已在the standard library中定义,因此您不能将其更改为Map<TKey, TValue[]>
或Map<TKey, TValue extends any[]>
甚至Map<K, V extends any[]>
。您只需将其保留为Map<K, V>
。
您要添加的新方法要求V
为数组类型才能有意义。而且您不能在声明中约束V
。你被卡住了吗?没有!幸运的是,您可以使用称为this
parameter的TypeScript功能。这个想法是,您可以在函数或方法的参数列表的开头添加一个名为this
的参数。当您调用该方法时,您不会使用this
参数,但是TypeScript将强制您仅在其this
上下文匹配的对象上调用该方法。
像这样:
// no error
declare global {
interface Map<K, V> {
SetInArray<V>(this: Map<K, V[]>, key: K, value: V): boolean;
}
}
Map.prototype.SetInArray = function <K, V>(this: Map<K, V[]>, key: K, value: V): boolean {
let isNew: boolean = false;
if (this.has(key) == false) {
this.set(key, []);
isNew = true;
}
let items: V[] = this.get(key)!;
items.push(value);
return isNew;
};
让我们尝试一下:
const numberArrayMap = new Map<string, number[]>();
numberArrayMap.set("a", [1, 2, 3])
numberArrayMap.SetInArray("a", 4); // okay
const numberMap = new Map<string, number>();
numberMap.set("a", 4)
numberMap.SetInArray("a", 4); // error
// The 'this' context of type 'Map<string, number>' is not assignable
// to method's 'this' of type 'Map<string, number[]>'.
// Type 'number' is not assignable to type 'number[]'.
我认为这正是您想要的行为。请注意,numberArrayMap
如何让您调用SetInArray()
,而numberMap
却没有,并且错误告诉您即使Map
确实具有SetInArray
方法,您也可以由于this
上下文不兼容而无法调用它。
好的,希望能有所帮助。祝你好运!