Використання синтаксису поширення та нового Set () із машинописом


92

Я використовую такий код, щоб отримати унікальні номери:

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

Однак звіт про машинопис повідомляє про наступну помилку: Тип 'Set' не є типом масиву. Я не ніндзя машинопису, хтось може сказати мені, що тут не так?


4
Я думаю, що це лише помилка Typescript, якщо версія, яку ви використовуєте, вимагає підтримки ES2015.
Пойнті

1
@Pointy Вибачте за це, я повинен включити версію tsc, яка є 1.6.2
Eggy

Відповіді:


40

Ця функція відсутня. На даний момент TypeScript підтримує лише ітерабелі на масивах.


Дякую за роз'яснення. Я буду використовувати .filter () або щось інше, щоб виконати роботу. Я також знайшов кілька питань на github щодо цієї конкретної помилки. Я буду стежити за цим у наступних випусках.
Eggy,

96

Оновлення : за допомогою Typescript 2.3 тепер ви можете додавати "downlevelIteration": trueдо вашого tsconfig, і це буде працювати під час націлювання на ES5.

Недоліком downlevelIterationє те, що під час транспортування ТС доведеться впорхнути досить багато зразків. Один рядок із запитання транслюється з 21 рядком доданої шаблонної таблиці: (станом на Typescript 2.6.1)

Цей шаблонний шаблон буде введений один раз у файл, який використовує ітерацію нижчого рівня, і цей шаблонний "importHelpers"шаблон можна зменшити, використовуючи опцію через tsconfig. (Див. Цей допис у блозі про ітерацію нижчого рівня та importHelpers)

Як варіант, якщо підтримка ES5 для вас не має значення, ви завжди можете просто націлити на "es6", в цьому випадку оригінальний код працює, не потребуючи прапора "downlevelIteration".


Оригінальна відповідь:

Це, здається, химерність транпіляції ES6. ...Оператор повинен працювати на все , що має властивість ітератора, (до яких звертається obj[Symbol.iterator]) і набори мають цю властивість.

Щоб обійти цю проблему , ви можете використовувати , Array.fromщоб перетворити набір в масив першим: ...Array.from(new Set([1, 2, 3, 1, 1])).


@Restam: Чи надає машинопис поліфіли для Array.from в IE, якщо "target": "es5" у tsconfig.json?
jackOfAll

1
@jackOfAll Ні, Typescript не робить для вас жодного полізаповнення прототипів. Якщо ви встановите "target": "es5", це має призвести до помилки компілятора, якщо ви намагаєтесь використовувати метод, який потрібно заповнити.
Retsam

1
@Restam відмінне рішення з Array.from. Здається, більшість інших людей просто відмовляються від цього. дякую за реальне рішення!
rayepps

Це не помилка, вони просто не підтримують її для es5цілі (див. Github.com/Microsoft/TypeScript/issues/4031 ). Array.fromмає працювати, якщо у вашому списку в tsconfig є es2015або вище ( es2017, esnext) lib.
Simon Hänisch

1
@ SimonHänisch Дякую за посилання: я оновив свою відповідь, я більше не називаю це "помилкою", а "химерною трансляцією", що, мабуть, є більш точним терміном. Я також додав інформацію про варіант ітерації нижчого рівня за цим посиланням, що також вирішує вихідну проблему.
Ретсам,

67

Ви також можете використовувати метод Array.from для перетворення набору в масив

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


Який сенс поширювати масив лише для того, щоб відновити його в новому масиві?
Роббі Корнеліссен,

1
Якщо неможливо націлити "es6", у tsconfig. А використання оператора Set with spread потрібно, як би ви це зробили?
Nate Getch

Справа в тому, що якщо ви використовуєте Array.from(), вам більше не потрібен оператор поширення. Це просто додає накладних витрат. let uniques = Array.from(new Set([1, 2, 3, 1, 1]));
Роббі Корнеліссен,

8

Вам потрібно встановити "target": "es6",у своєму tsconfig.


0

Щоб це працювало, вам потрібно або "target": "ES6" (або вище), або "downlevelIteration": true у compilerOptions вашого tsconfig.json. Це вирішило мою проблему і працюю добре чи я, сподіваюся, це допоможе і вам.


-1

У Javascript:

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

У машинописі:

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

У стані реагування (setState):

setCart(Array.from(new Set([...cart, {title: 'Sample', price: 20}])));
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.