Menggunakan sintaks menyebar dan Set baru () dengan skrip ketikan

92

Saya menggunakan kode berikut untuk mendapatkan nomor unik:

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

Namun, laporan ketikan kesalahan berikut: Jenis 'Set' bukan jenis array. Saya bukan ninja naskah, bisakah seseorang memberi tahu saya apa yang salah di sini?

Eggy
sumber
4
Saya pikir itu hanya bug Typecript, jika versi yang Anda gunakan mengklaim mendukung ES2015.
Pointy
1
@ Pointy Maaf tentang itu, saya harus menyertakan versi tsc yang 1.6.2
Eggy

Jawaban:

40

Ini adalah fitur yang hilang. TypeScript hanya mendukung iterable pada Array saat ini.

basarat
sumber
Terima kasih atas klarifikasinya. Saya akan menggunakan .filter () atau sesuatu yang lain untuk menyelesaikan pekerjaan. Saya juga menemukan beberapa masalah di github tentang kesalahan khusus ini. Saya akan mengawasi ini di rilis mendatang.
Eggy
96

Pembaruan : Dengan Typecript 2.3, Anda sekarang dapat menambahkan "downlevelIteration": trueke tsconfig Anda, dan ini akan bekerja sambil menargetkan ES5.

Sisi negatifnya downlevelIterationadalah TS harus menginjeksikan cukup banyak boilerplate saat transpiling. Satu baris dari pertanyaan tersebut transparan dengan 21 baris boilerplate yang ditambahkan: (sesuai dengan Ketikan 2.6.1)

Boilerplate ini akan diinjeksi satu kali per file yang menggunakan iterasi downlevel, dan boilerplate ini dapat dikurangi menggunakan "importHelpers"opsi melalui tsconfig. (Lihat posting blog ini tentang iterasi downlevel dan importHelpers)

Alternatifnya, jika dukungan ES5 tidak penting bagi Anda, Anda selalu dapat menargetkan "es6" sejak awal, dalam hal ini kode asli berfungsi tanpa memerlukan panji "downlevelIteration".


Jawaban asli:

Ini tampaknya merupakan permainan kata-kata transpilasi ES6 yang diketik. The ...Operator harus bekerja pada apa pun yang memiliki properti iterator, (Diakses oleh obj[Symbol.iterator]) dan Set memiliki properti itu.

Untuk bekerja di sekitar ini, Anda dapat menggunakan Array.fromuntuk mengkonversi set ke array pertama: ...Array.from(new Set([1, 2, 3, 1, 1])).

Retsam
sumber
@Restam: Apakah skrip ketikan menyediakan polyfill untuk Array.from di IE jika "target": "es5" di tsconfig.json?
jackOfAll
1
@jackOfAll Tidak, Typecript tidak melakukan polfill prototipe apa pun untuk Anda. Jika Anda menyetel "target": "es5", ini akan memberi Anda kesalahan kompiler jika Anda mencoba menggunakan metode yang perlu di-polyfill.
Retsam
1
@Restam solusi hebat dengan Array.from. Kebanyakan orang lain tampaknya menyerah begitu saja. terima kasih untuk solusi nyata!
rayepps
Ini bukan bug, mereka hanya tidak mendukungnya untuk es5target (lihat github.com/Microsoft/TypeScript/issues/4031 ). Array.fromharus berfungsi jika Anda memiliki es2015atau lebih tinggi ( es2017, esnext) dalam libdaftar Anda di tsconfig.
Simon Hänisch
1
@ SimonHänisch Terima kasih untuk tautannya: Saya telah memperbarui jawaban saya, saya tidak lagi menyebutnya "bug", tetapi "kekhasan transpilasi", yang mungkin merupakan istilah yang lebih akurat. Saya juga menambahkan informasi tentang opsi iterasi ke bawah dari tautan itu, yang juga memecahkan masalah asli.
Retsam
67

Anda juga dapat menggunakan metode Array.from untuk mengubah Set ke Array

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

Nate Getch
sumber
Apa gunanya menyebarkan larik hanya untuk menangkapnya kembali dalam larik baru?
Robby Cornelissen
1
Jika tidak memungkinkan untuk menargetkan "es6", di tsconfig. Dan menggunakan Set dengan operator spread diperlukan, bagaimana cara melakukannya?
Nate Getch
Intinya adalah jika Anda menggunakan Array.from(), Anda tidak lagi membutuhkan operator penyebaran. Itu hanya menambah biaya overhead. let uniques = Array.from(new Set([1, 2, 3, 1, 1]));
Robby Cornelissen
8

Anda perlu mengaturnya "target": "es6",di tsconfig Anda.

phil294
sumber
0

Untuk membuatnya bekerja, Anda memerlukan "target": "ES6" (atau lebih tinggi) atau "downlevelIteration": true di compilerOptions tsconfig.json Anda. Ini menyelesaikan masalah saya dan bekerja dengan baik atau saya. Semoga ini akan membantu Anda juga.

Mayur Saner
sumber
-1

Dalam Javascript:

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

Dalam Ketikan:

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

Di React State (setState):

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