Sử dụng cú pháp lây lan và Set () mới với bảng chữ


92

Tôi đang sử dụng mã sau để nhận các số duy nhất:

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

Tuy nhiên, chỉ định kiểu báo cáo lỗi sau: Loại 'Đặt' không phải là kiểu mảng. Tôi không phải là ninja đánh máy, ai đó có thể cho tôi biết có gì sai ở đây không?


4
Tôi nghĩ đó chỉ là một lỗi Typecript, nếu phiên bản bạn đang sử dụng tuyên bố hỗ trợ ES2015.
Pointy

1
@Pointy Xin lỗi về điều đó, tôi nên bao gồm phiên bản tsc là 1.6.2
Eggy

Câu trả lời:


40

Đây là một tính năng còn thiếu. Hiện tại, TypeScript chỉ hỗ trợ lặp lại trên Mảng.


Cảm ơn đã làm rõ. Tôi sẽ sử dụng .filter () hoặc một cái gì đó khác để hoàn thành công việc. Tôi cũng tìm thấy một số vấn đề trên github về lỗi cụ thể này. Tôi sẽ theo dõi điều này trong các bản phát hành trong tương lai.
Eggy

96

Cập nhật : Với Typescript 2.3, bây giờ bạn có thể thêm "downlevelIteration": truevào tsconfig của mình và điều này sẽ hoạt động khi nhắm mục tiêu ES5.

Nhược điểm của downlevelIterationnó là TS sẽ phải tiêm khá nhiều boilerplate khi chuyển vị. Một dòng duy nhất từ ​​câu hỏi chuyển tiếp với 21 dòng bảng soạn sẵn được thêm vào: (kể từ Loại chỉ số 2.6.1)

Bản soạn sẵn này sẽ được đưa vào một lần cho mỗi tệp sử dụng lặp lại cấp độ thấp và bản trình tự này có thể được giảm bớt bằng cách sử dụng "importHelpers"tùy chọn thông qua tsconfig. (Xem bài đăng blog này về lặp lại cấp độ thấp hơn và importHelpers)

Ngoài ra, nếu hỗ trợ ES5 không quan trọng đối với bạn, bạn luôn có thể nhắm mục tiêu "es6" ngay từ đầu, trong trường hợp đó mã gốc hoạt động mà không cần cờ "downlevelIteration".


Câu trả lời ban đầu:

Đây dường như là một câu trả lời sai cách chuyển mã ES6. Các ...nhà điều hành nên làm việc trên bất cứ điều gì mà có một tài sản iterator, (Accessed bằng obj[Symbol.iterator]) và Bộ có tài sản đó.

Để làm việc này, bạn có thể sử dụng Array.fromđể chuyển đổi các thiết lập để một mảng đầu tiên: ...Array.from(new Set([1, 2, 3, 1, 1])).


@Restam: Có phải typecript cung cấp polyfills cho Array.from trong IE nếu "target": "es5" trong tsconfig.json không?
jackOfAll

1
@jackOfAll Không, Typescript không thực hiện bất kỳ thao tác điền nguyên mẫu nào cho bạn. Nếu bạn đặt "target": "es5", nó sẽ gây ra lỗi trình biên dịch nếu bạn cố gắng sử dụng một phương thức cần được polyfilled.
Retsam 29/07/17

1
@Restam giải pháp tuyệt vời với Array.from. Hầu hết những người khác dường như chỉ từ bỏ điều này. cảm ơn cho một giải pháp thực sự!
rayepps

Đó không phải là lỗi, họ không hỗ trợ nó cho es5mục tiêu (xem github.com/Microsoft/TypeScript/issues/4031 ). Array.fromsẽ hoạt động nếu bạn có es2015hoặc cao hơn ( es2017, esnext) trong libdanh sách của bạn trong tsconfig.
Simon Hänisch

1
@ SimonHänisch Cảm ơn vì liên kết: Tôi đã cập nhật câu trả lời của mình, tôi không còn gọi nó là "lỗi" nữa, mà là "lỗi chuyển ngữ", có lẽ là một thuật ngữ chính xác hơn. Tôi cũng đã thêm thông tin về tùy chọn lặp lại cấp dưới từ liên kết đó, điều này cũng giải quyết được vấn đề ban đầu.
Retsam

67

Bạn cũng có thể sử dụng phương thức Array.from để chuyển Tập hợp thành Mảng

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


Điểm của việc dàn trải mảng chỉ để lấy lại nó trong một mảng mới là gì?
Robby Cornelissen

1
Nếu không thể nhắm mục tiêu "es6", trong tsconfig. Và việc sử dụng Set với toán tử spread là bắt buộc, bạn sẽ làm như thế nào?
Nate Getch 14/02/18

Vấn đề là nếu bạn sử dụng Array.from(), bạn không cần toán tử spread nữa. Nó chỉ thêm chi phí. let uniques = Array.from(new Set([1, 2, 3, 1, 1]));
Robby Cornelissen

8

Bạn cần thiết lập "target": "es6",tsconfig của mình.


0

Để làm cho nó hoạt động, bạn cần "target": "ES6" (hoặc cao hơn) hoặc "downlevelIteration": true trong compilerOptions của tsconfig.json của bạn. Điều này đã giải quyết vấn đề của tôi và hoạt động tốt hoặc tôi. Hy vọng nó cũng sẽ giúp bạn.


0

Trong Javascript:

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

Trong phần Typecript:

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

Trong trạng thái React (setState):

setCart(Array.from(new Set([...cart, {title: 'Sample', price: 20}])));
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.