使用扩展语法和带有Typescript的新Set()


91

我正在使用以下代码来获取唯一编号:

let uniques = [ ...new Set([1, 2, 3, 1, 1]) ]; // [1, 2, 3]

但是,打字稿报告以下错误:Type'Set '不是数组类型。 我不是忍者打字稿,有人可以告诉我这是怎么回事吗?


4
我认为这只是Typescript错误,如果您使用的版本声称支持ES2015。
尖尖的2015年

1
@Pointy抱歉,我应该包含1.6.2版本的tsc
Eggy 2015年

Answers:


39

这是缺少的功能。TypeScript目前仅支持数组上的可迭代对象。


感谢您的澄清。我将使用.filter()或其他方法来完成工作。我在github上也没有发现关于此特定错误的问题。在以后的版本中,我将密切注意这一点。
Eggy 2015年

95

更新:使用Typescript 2.3,您现在可以将其添加"downlevelIteration": true到tsconfig中,并且在定位ES5时可以使用。

不利的downlevelIteration一面是,TS在转桩时必须注入很多样板。问题中的单行转换为添加了21行样板的代码:(自打字稿2.6.1起)

每个使用下层迭代的文件都会将此样板注入一次,并且可以使用该"importHelpers"选项通过tsconfig减少该样板。(有关下级迭代,请参见此博客文章,以及importHelpers

另外,如果对您而言ES5支持无关紧要,则始终始终可以首先定位“ es6”,在这种情况下,原始代码可以使用而无需“ downlevelIteration”标志。


原始答案:

这似乎是打字稿ES6的翻译怪癖。该...经营者应在任何有一个iterator属性(由工作访问的obj[Symbol.iterator]),并设置有属性。

要解决此问题,可以Array.from先将集合转换为数组:...Array.from(new Set([1, 2, 3, 1, 1]))


@Restam:如果tsconfig.json中的“ target”:“ es5”,打字稿是否为IE中的Array.from提供polyfill?
jackOfAll

1
@jackOfAll不,Typescript不会为您做任何原型的填充。如果设置“ target”:“ es5”,则在尝试使用需要进行多填充的方法时,应该会出现编译器错误。
Retsam

1
@Restam的绝佳解决方案Array.from。大多数其他人似乎只是放弃了这一点。感谢您提供真正的解决方案!
rayepps

这不是错误,他们只是不为es5目标提供支持(请参阅github.com/Microsoft/TypeScript/issues/4031)。Array.from如果您在tsconfig中的列表中es2015具有()或更高(es2017esnextlib
西蒙·海尼斯(SimonHänisch),

1
@SimonHänisch感谢您的链接:我已经更新了答案,我不再称它为“ bug”,而是一个“ transpilation quirk”,这可能是一个更准确的术语。我还从该链接添加了有关下层迭代选项的信息,这也解决了原始问题。
Retsam

67

您也可以使用Array.from方法将Set转换为Array

let uniques = Array.from(new Set([1, 2, 3, 1, 1])) ;
console.log(uniques);


散布阵列以仅将其重新捕获到新阵列中有什么意义?
罗比·科尼利森

1
如果不可能以tsconfig为目标“ es6”。并且需要将Set与传播算子一起使用,您将如何做?
Nate Getch

关键是,如果使用Array.from(),则不再需要传播运算符。它只会增加开销。let uniques = Array.from(new Set([1, 2, 3, 1, 1]));
罗比·科尼利森


0

要使其工作,您需要在tsconfig.json的editorOptions中使用“ target”:“ ES6”(或更高版本)或“ downlevelIteration”:true。这解决了我的问题,对我或我都有益。希望它对您也有帮助。


-1

用Javascript:

[ ...new Set([1, 2, 3, 1, 1]) ]

在打字稿中:

Array.from(new Set([1, 2, 3, 1, 1]))

在React State(setState)中:

setCart(Array.from(new Set([...cart, {title: 'Sample', price: 20}])));
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.