简体   繁体   English

在打字稿中使用扩展语法和 new Set()

[英]Using spread syntax and new Set() with typescript

I am using following code to get unique numbers:我正在使用以下代码来获取唯一编号:

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

However, typescript report following error: Type 'Set' is not an array type.但是,打字稿报告以下错误: Type 'Set' is not an array type。 I am not typescript ninja, could someone tell me what is wrong here?我不是打字稿忍者,有人能告诉我这里有什么问题吗?

Update : With Typescript 2.3, you can now add "downlevelIteration": true to your tsconfig, and this will work while targeting ES5.更新:使用 Typescript 2.3,您现在可以将"downlevelIteration": true downlevelIteration "downlevelIteration": true添加到您的 tsconfig,这将在面向 ES5 时起作用。

The downside of downlevelIteration is that TS will have to inject quite a bit of boilerplate when transpiling.的缺点downlevelIteration是TS将有transpiling时注入相当多的样板。 The single line from the question transpiles with 21 lines of added boilerplate: (as of Typescript 2.6.1)问题中的单行转换为 21 行添加的样板:(从 Typescript 2.6.1 开始)

 var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spread = (this && this.__spread) || function () { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; }; var uniques = __spread(new Set([1, 2, 3, 1, 1])); console.log(uniques);

This boilerplate will be injected once per file that uses downlevel iteration, and this boilerplate can be reduced using the "importHelpers" option via the tsconfig.这个样板将在每个使用下级迭代的文件中注入一次,并且可以通过"importHelpers"使用"importHelpers"选项减少这个样板。 (See this blogpost on downlevel iteration and importHelpers ) (请参阅有关importHelpers迭代和importHelpers 博客importHelpers

Alternatively, if ES5 support doesn't matter for you, you can always just target "es6" in the first place, in which case the original code works without needing the "downlevelIteration" flag.或者,如果 ES5 支持对您来说无关紧要,您始终可以首先定位“es6”,在这种情况下,原始代码无需“downlevelIteration”标志即可工作。


Original answer:原答案:

This seems to be a typescript ES6 transpilation quirk .这似乎是一个打字稿 ES6 转译的怪癖。 The ... operator should work on anything that has an iterator property, (Accessed by obj[Symbol.iterator] ) and Sets have that property. ...运算符应该适用于任何具有迭代器属性的东西,(由obj[Symbol.iterator]访问)并且集合具有该属性。

To work around this, you can use Array.from to convert the set to an array first: ...Array.from(new Set([1, 2, 3, 1, 1])) .要解决此问题,您可以先使用Array.from将集合转换为数组: ...Array.from(new Set([1, 2, 3, 1, 1]))

You can also use Array.from method to convert the Set to Array您还可以使用 Array.from 方法将 Set 转换为 Array

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

This is a missing feature.这是一个缺失的功能。 TypeScript only supports iterables on Arrays at the moment. TypeScript 目前仅支持数组上的可迭代对象。

In Javascript:在 JavaScript 中:

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

In Typescript:在打字稿中:

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

In React State (setState):在反应状态(setState)中:

setCart(Array.from(new Set([...cart, {title: 'Sample', price: 20}])));

您需要在"target": "es6",设置"target": "es6",

To make it work, you either need "target": "ES6" (or higher) or "downlevelIteration": true in the compilerOptions of your tsconfig.json .要使其工作,您需要在 tsconfig.json 的 compilerOptions 中使用 "target": "ES6"(或更高版本)或 "downlevelIteration": true。 This resolved my issue and working good or me.Hope it will help you also.这解决了我的问题并且工作良好或我。希望它也能帮助你。

Now, you can use Set in your Typescript setup (No need to target es6 ):现在,您可以在 Typescript 设置中使用Set (无需定位es6 ):

In you tsconfig.json , add this line:在您tsconfig.json ,添加以下行:

{
  "compilerOptions": {
    /* Visit https://aka.ms/tsconfig.json to read more about this file */

    
    "downlevelIteration": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
    
  },
  ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM