15

I want to extract all the unique properties from an array of objects, you can do so in ES6 very cleanly using the spread operator and the Set so:

var arr = [ {foo:1, bar:2}, {foo:2, bar:3}, {foo:3, bar:3} ]   
const uniqueBars = [... new Set(arr.map(obj => obj.bar))];

>> [2, 3]

However, in TypeScript 1.8.31 this gives me the build error:

Cannot find name 'Set'

I know I can force VS to ignore it by using

declare var Set;

But I'm hoping for something TypeScript will compile into non-ES6 so that it could be used on older systems.

Does anyone know if there's such a feature I could use?

Edit:

Actually, even when I use declare var Set;, the above code compiles but throws this error repeatedly, so I'm not sure how to use it even without compiling down:

Uncaught TypeError: (intermediate value).slice is not a function

How can I update my code to use Set in TypeScript?

Charles Clayton
  • 17,005
  • 11
  • 87
  • 120
  • 2
    Possible duplicate of [Angular 2 typescript can't find names](http://stackoverflow.com/questions/33332394/angular-2-typescript-cant-find-names) – jonrsharpe Jan 21 '17 at 19:28
  • TS doesn't have to have an equivalent of this, because TS transpiles to JS, and `Set` is polyfillable JS feature. This is a duplicate, http://stackoverflow.com/a/41608156/3731501 in particular. – Estus Flask Jan 21 '17 at 20:01
  • 1
    I suppose you could also [compile the typescript to ES6 code](http://stackoverflow.com/questions/30439869/can-typescript-compile-to-es6-code) and then transpile that to ES5 with something like babel. That would allow you to use all the ES6 collections. – jfriend00 Jan 21 '17 at 20:29

3 Answers3

8

This worked for me.

One of the issues appears to be that typescript trys to use

ERROR TypeError: (intermediate value).slice is not a function

instead of Array.from();

in any event this code worked for me in my Angular 4 applicaiton

Array.from(new Set(Array)).sort(this.compareNumbers)

hope this helps someone

Christian Matthew
  • 4,014
  • 4
  • 33
  • 43
  • 1
    I'm getting error `Argument of type 'ArrayConstructor' is not assignable to parameter of type 'Iterable<{}>'. Property '[Symbol.iterator]' is missing in type 'ArrayConstructor'.` – Abhishek Ekaanth Mar 28 '18 at 08:52
  • Were you able to resolve this issue? This still works for me in production – Christian Matthew Mar 06 '19 at 18:57
  • so, what I did was the same, `let set = new Set();` while `import 'core-js/es6/set';` imported in my polyfills.ts – Abhishek Ekaanth Mar 07 '19 at 04:27
  • 1
    Thank you! Confirming `[...Array.from(new Set([...arr1, ...arr2]))]` works, but `[...(new Set([...arr1, ...arr2]))]` gave the `(intermediate value).slice is not a function` error. – Boris Yakubchik May 15 '19 at 15:45
4

No. If you compile to ES5 or older Typescript only adds the syntactic changes from ES6. It doesn't add any of the standard library objects.

If you want those I suggest you look into something like core.js

toskv
  • 30,680
  • 7
  • 72
  • 74
1

You can use this type script library. Or maybe create your one set class using reference from this library

jfriend00
  • 683,504
  • 96
  • 985
  • 979
Yogesh
  • 4,546
  • 2
  • 32
  • 41