let a : any;
let m = new Map<any, any>(Object.keys(a).map(prop => ([prop.x, prop.y])));
带有esnext
目标的会产生错误
file:&#39; file:///c%3A/GIT/MainLine/members/src/tasks/list/decTest2.ts' 严重性:&#39;错误&#39; 消息:&#39;类型的参数&#39;任何[] []&#39;不能分配给类型参数&#39; Iterable&lt; [any,any]&gt;&#39;。 财产类型&#39; [Symbol.iterator]&#39;是不相容的。 输入&#39;()=&gt; IterableIterator&#39;不能分配给&#39;()=&gt;迭代器&lt; [any,any]&gt;&#39;。 输入&#39; IterableIterator&#39;不能指定类型&#39; Iterator&lt; [any,any]&gt;&#39;。 财产类型&#39; next&#39;是不相容的。 输入&#39;(值?:any)=&gt; IteratorResult&#39;不能分配类型&#39;(值?:any)=&gt; IteratorResult&lt; [any,any]&gt;&#39;。 输入&#39; IteratorResult&#39;不能指定类型&#39; IteratorResult&lt; [any,any]&gt;&#39;。 输入&#39;任何[]&#39;不能指定类型&#39; [any,any]&#39;。 财产&#39; 0&#39;类型中缺少任何[]&#39;。&#39; at:&#39; 4,27&#39; 来源:&#39; ts&#39;
这很奇怪,因为
let m2 = new Map<any, any>([[1, 2], [2, 3], ['a', 'b']])
编译好。我需要在第一个样本中添加什么才能进行编译?
请注意,我确实知道
let m2 = new Map<any, any>(<any>[[1, 2], [2, 3], ["a", 'b']])
也会修复它,但我想了解为什么会出错,看看是否有更好的解决方法。
答案 0 :(得分:2)
问题是TypeScript不确定您的数组是否是该上下文中的元组或普通数组。类型参数推断尝试仅将其参数用作推理站点。
因此,在调用map
时,它不会从new Map<any, any>(...)
的参数类型中推断出map
的返回类型。
TypeScript 2.4正朝着这个方向发展some changes,your specific scenario was brought up。关于问题本身的讨论和进展可以是tracked here。
作为一种变通方法,您可以编写显式返回类型
(prop): [any, any] => [prop.x, prop.y]
或者您可以为map
提供显式类型参数
Object.keys(a).map<[any, any]>(...)
请注意,在任何一种情况下,TypeScript都会抓住x
上y
和string
不是有效属性的错误。
答案 1 :(得分:1)
从它的外观来看,编译器根本无法推断map<U>
的预期类型,如果你明确地设置它,那很好:
let a: any;
let b = Object.keys(a).map<[any, any]>(key => [key, a[key]]);
let m = new Map<any, any>(b);
问题是它放弃并返回any[][]
,这对于预期的类型元组无效:[any, any][]
答案 2 :(得分:1)
这里的关键是你的map
回调函数返回的类型。
prop => [prop.x, prop.y]
TypeScript不会自动从数组文字中推断出元组类型,比如你要返回的数组 - 它会假设一个常规数组类型(在本例中为any[]
),这意味着你调用{{1将返回 类型的数组(在本例中为map
)。
但是,any[][]
对象构造函数需要一个特定元组类型的数组。在这种情况下,它将寻找Map
的数组或可迭代(为简单起见,我们将其称为[any, any]
。)
由于TypeScript不会自动从您在[any, any][]
中创建的数组中推断出元组类型,因此满足类型检查器的最快方法是指定函数的返回值以表明您打算使用它用作元组:
map
在显式设置回调的返回值类型的情况下,(prop): [any, any] => [prop.x, prop.y]
将返回类型map
的值,该值满足[any, any][]
构造函数。