Using spread syntax and new Set() with typescript
JavascriptTypescriptEcmascript 6Spread SyntaxJavascript 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
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.