gpt4 book ai didi

angular - 无法在 TypeScript 中为 Map 编写扩展方法

转载 作者:搜寻专家 更新时间:2023-10-30 21:21:30 24 4
gpt4 key购买 nike

我是 Angular/TS 的新用户,喜欢使用扩展方法。他们在标准类型上工作得很好,但现在我正在尝试为 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 {};

请指教

谢谢

最佳答案

有一些问题(除了常识是 you should not extend native object prototypes 之外)。第一个是当你声明一个泛型接口(interface)或类型时,它的类型参数必须是一个裸名,而不是其他类型的函数。所以你不能有

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,您根本无法调用它上下文。

好的,希望对你有帮助。祝你好运!

关于angular - 无法在 TypeScript 中为 Map<TKey, TValue[]> 编写扩展方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53546780/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com