2017-05-25 148 views
3
let a : any; 
let m = new Map<any, any>(Object.keys(a).map(prop => ([prop.x, prop.y]))); 

esnext目标产生错误打字稿错误编译地图

文件: '文件:///c%3A/GIT/MainLine/members/src/tasks/list/decTest2.ts' 严重程度:'错误' 消息:'类型'any [] []'的参数不可分配给类型为'Iterable < [any,any]>'的参数。 属性类型'[Symbol.iterator]'不兼容。 类型'()=> IterableIterator'不可分配给类型'()=>迭代器< [any,any]>'。 类型'IterableIterator'不可分配为键入'Iterator < [any,any]>'。 属性'next'的类型不兼容。 类型'(value ?: any)=> IteratorResult'不可分配给类型'(value ?: any)=> IteratorResult < [any,any]>'。 类型'IteratorResult'不可分配为键入'IteratorResult < [any,any]>'。 类型'any []'不可分配为键入'[any,any]'。 类型'any []'中缺少属性'0'。' 在: '4,27' 源: 'TS'

这很奇怪,因为

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

prop是一个字符串。你确定你不是要写一个[prop] .x而不是prop.x? – Sebastian

回答

1

问题是,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]>(...) 

注意,在这两种情况下,打字稿捕捉错误xy不是string s上的有效属性。

+0

加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][]

+0

哦整齐 - 我不知道Array.prototype.map可以采用泛型类型参数 –

1

这里的关键是你的map回调函数返回的类型。

prop => [prop.x, prop.y] 

打字稿不会自动从数组常量像你返回—它会代之以假定一个普通的数组类型,这意味着你要map调用将返回数组(在这种情况下,any[])推断的元组类型类型的数组(在这种情况下为any[][])。但是,对象构造函数Map期望具有特定元组类型的数组。在这种情况下,它将寻找一个数组或[any, any](我们将简称为[any, any][])。

由于TypeScript不会自动推断您在map中创建的数组中的元组类型,因此满足类型检测器的最快方法是指定函数的返回值以表明您打算将它用作一个元组:

(prop): [any, any] => [prop.x, prop.y] 

随着回调的返回值的类型被明确设置,map将返回[any, any][]类型的值满足Map构造。

+0

加1 - 感谢吨。我会留下帖子打开一下,但可靠的信息 - 谢谢! –