Using spread syntax and new Set() with typescript

JavascriptTypescriptEcmascript 6Spread Syntax

Javascript Problem Overview


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. I am not typescript ninja, could someone tell me what is wrong here?

Javascript Solutions


Solution 1 - Javascript

Update: With Typescript 2.3, you can now add "downlevelIteration": true to your tsconfig, and this will work while targeting ES5.

The downside of downlevelIteration is that TS will have to inject quite a bit of boilerplate when transpiling. The single line from the question transpiles with 21 lines of added boilerplate: (as of 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. (See this blogpost on downlevel iteration and 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.


Original answer:

This seems to be a typescript ES6 transpilation quirk . The ... operator should work on anything that has an iterator property, (Accessed by obj[Symbol.iterator]) and Sets have that property.

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])).

Solution 2 - Javascript

You can also use Array.from method to convert the Set to Array

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

Solution 3 - Javascript

This is a missing feature. TypeScript only supports iterables on Arrays at the moment.

Solution 4 - Javascript

In Javascript:

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

In Typescript:

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

In React State (setState):

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

Solution 5 - Javascript

You need to set "target": "es6", in your tsconfig.

Solution 6 - Javascript

Now, you can use Set in your Typescript setup (No need to target es6):

In you tsconfig.json, add this line:

{
  "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'. */
    
  },
  ...
}

Solution 7 - Javascript

To make it work, you either need "target": "ES6" (or higher) or "downlevelIteration": true in the compilerOptions of your tsconfig.json . This resolved my issue and working good or me.Hope it will help you also.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEggyView Question on Stackoverflow
Solution 1 - JavascriptRetsamView Answer on Stackoverflow
Solution 2 - JavascriptNate GetchView Answer on Stackoverflow
Solution 3 - JavascriptbasaratView Answer on Stackoverflow
Solution 4 - JavascriptNajathiView Answer on Stackoverflow
Solution 5 - Javascriptphil294View Answer on Stackoverflow
Solution 6 - JavascriptShivam JhaView Answer on Stackoverflow
Solution 7 - JavascriptMayur SanerView Answer on Stackoverflow