- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我是 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/
我实现了一个字典如下: Dictionary dictionary; 我已经定义了Equals()和 GetHashCode()在ErrorHashKey类(class)。我目前正在为该项目编写一些文
IList除了 SortedList.Keys 不支持的操作外,接口(interface)还包括按索引访问属性如 Add , Remove , 和 Insert . A ReadOnlyCollect
我有一个 Enumerable> .我想创建一个 bool TryGetValue(TKey, out TValue)它的扩展方法就像它在 Dictionary 中可用一样. 我试过了 public
只是覆盖 TKey 中的 Equals 没有帮助。 public override bool Equals(object obj) { /* ... */ } ... Equals() 永远不会被调
作为MSDN says ConcurrentDictionary Class 表示一个线程安全的键值对集合,可以被多个线程同时访问。 但据我所知,System.Collections.Concurre
我一直无法阐明 ILookup 之间的差异和 IGrouping ,并且很好奇我现在是否理解正确。 LINQ 通过生成 IGrouping 的序列使问题更加复杂项目同时还给我 ToLookup扩展方法
这似乎是这个 question 的副本,它会问“SortedList 和 SortedDictionary 有什么区别?”不幸的是,答案只是引用了 MSDN 文档(其中明确指出两者之间存在性能和内存使
我正在尝试创建自定义 ReadOnlyDictionary对于.NET 4.0。方法是保持私有(private) Dictionary对象以及标志以确定是否允许添加/删除和项目分配。 这很好用,但我想
我想这并不重要,我只是好奇。 如果字典和查找之间的区别是一个是一对一的,另一个是一对多的,那么不会通过另一个更具体/派生的版本来字典吗? 查找是键/值对的集合,其中键可以重复。字典是键/值对的集合,其
我想通过例子来理解TSource,Tkey的概念。 我们有代码 class Pet { public string Name { get; se
我想在给定 Dictionary 的情况下获取 TKey 和 TValue 的类型类型。 例如。如果类型是 Dictionary我想知道如何获得keyType = typeof(Int32) 和val
我想在给定 Dictionary 的情况下获取 TKey 和 TValue 的类型类型。 例如。如果类型是 Dictionary我想知道如何获得keyType = typeof(Int32) 和val
好的 - 所以我知道构建一个提供功能的工厂方法很简单;但鉴于 Dictionary是 IEnumerable> ,它不应该有一个等价于例如List 的Ctor吗?的ctor(IEnumerable r
我有一个 ILookup我想返回 ILookup其中 Derived实现或扩展 Base . 目前我使用SelectMany()然后 ToLookup()首先提取ILookup的键值对进公寓IEnum
我正在尝试存储 Linq 所需的表达式 OrderBy数据结构中的子句,所以我可以去query = query.OrderBy(MySortExpression); OrderBy需要 System.
我有一个返回 IDictionary > 的函数. 我有另一个函数需要 IDictionary > . 我需要将第一个函数的返回传递给第二个函数。 编译器不想将第一个隐式转换为第二个。那么如何在 O(
我正在尝试构建一个通用存储库并使用 autofac 进行测试。我有以下界面: public interface IGenRepo where T : class { IQueryable It
我有一个字典如下: public enum Role { Role1, Role2, Role3, } public enum Action { Action1, Action2, Action3,
我认为转换 IDictionary> 相当简单反对 IDictionary> , 但是 var val = (IDictionary>)Value; 抛出 System.InvalidCastExce
我有一个 IDictionary TKey在哪里是一个类。我可以添加将索引器与 String 一起使用的能力吗?值而不是 TKey ? public class MyClass { public
我是一名优秀的程序员,十分优秀!