การใช้ไวยากรณ์การแพร่กระจายและ Set () ใหม่ด้วย typescript


95

ฉันใช้รหัสต่อไปนี้เพื่อรับหมายเลขเฉพาะ:

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

อย่างไรก็ตาม typescript รายงานข้อผิดพลาดต่อไปนี้: Type 'Set' ไม่ใช่ประเภทอาร์เรย์ ฉันไม่ใช่นินจานักพิมพ์มีใครบอกได้ไหมว่ามีอะไรผิดปกติที่นี่?


4
ฉันคิดว่านั่นเป็นเพียงข้อบกพร่องของ typescript หากเวอร์ชันที่คุณใช้อ้างว่ารองรับ ES2015
Pointy

1
@Pointy ขออภัยเกี่ยวกับเรื่องนี้ฉันควรรวมเวอร์ชันของ tsc ซึ่งเป็น 1.6.2
Eggy

คำตอบ:


46

นี่คือคุณสมบัติที่ขาดหายไป TypeScript สนับสนุนเฉพาะการเล่นซ้ำบนอาร์เรย์ในขณะนี้


ขอบคุณสำหรับคำชี้แจง ฉันจะใช้. filter () หรืออย่างอื่นเพื่อให้งานสำเร็จลุล่วง ฉันยังพบปัญหาเล็กน้อยใน github เกี่ยวกับข้อผิดพลาดนี้ ฉันจะคอยติดตามเรื่องนี้ในการเผยแพร่ในอนาคต
Eggy

103

อัปเดต : ด้วย typescript 2.3 ตอนนี้คุณสามารถเพิ่ม"downlevelIteration": truetsconfig ของคุณได้แล้วและจะใช้งานได้ในขณะที่กำหนดเป้าหมาย ES5

ข้อเสียdownlevelIterationคือ TS จะต้องฉีดหม้อไอน้ำเล็กน้อยเมื่อทำการขนส่ง บรรทัดเดียวจากคำถามปรากฏขึ้นโดยมีแผ่นสำเร็จรูปเพิ่ม 21 บรรทัด: (ณ typescript 2.6.1)

แผ่นต้นแบบนี้จะถูกฉีดหนึ่งครั้งต่อไฟล์ที่ใช้การวนซ้ำแบบลดระดับและแผ่นสำเร็จรูปนี้สามารถลดลงได้โดยใช้"importHelpers"ตัวเลือกผ่านทาง tsconfig (ดูบล็อกโพสต์นี้เกี่ยวกับการทำซ้ำระดับลงและimportHelpers)

หรืออีกวิธีหนึ่งหากการสนับสนุน ES5 ไม่สำคัญสำหรับคุณคุณสามารถกำหนดเป้าหมายเป็น "es6" ได้ตลอดเวลาซึ่งในกรณีนี้โค้ดดั้งเดิมจะทำงานได้โดยไม่ต้องใช้แฟล็ก "downlevelIteration"


คำตอบเดิม:

สิ่งนี้ดูเหมือนจะเป็นมุมแหลมการถ่ายทอด ES6 แบบ typescript ตัว...ดำเนินการควรทำงานกับทุกสิ่งที่มีคุณสมบัติตัววนซ้ำ (เข้าถึงโดยobj[Symbol.iterator]) และชุดที่มีคุณสมบัตินั้น

การทำงานรอบนี้คุณสามารถใช้การแปลงชุดไปยังอาร์เรย์แรก:Array.from...Array.from(new Set([1, 2, 3, 1, 1]))


@Restam: typescript ให้ polyfills สำหรับ 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ควรใช้งานได้ถ้าคุณมีes2015หรือสูงกว่า ( es2017, esnext) ในlibรายการของคุณใน tsconfig
Simon Hänisch

1
@ SimonHänischขอบคุณสำหรับลิงค์: ฉันได้อัปเดตคำตอบของฉันแล้วฉันไม่ได้เรียกมันว่า "ข้อผิดพลาด" อีกต่อไป แต่เป็น "มุมมองการถ่ายโอน" ซึ่งน่าจะเป็นคำที่ถูกต้องกว่า ฉันยังเพิ่มข้อมูลเกี่ยวกับตัวเลือกการวนซ้ำจากลิงก์นั้นซึ่งจะช่วยแก้ปัญหาเดิมได้ด้วย
Retsam

74

คุณยังสามารถใช้เมธอด Array.from เพื่อแปลง Set เป็น Array

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


อะไรคือจุดสำคัญของการแพร่กระจายอาร์เรย์เพื่อจับภาพในอาร์เรย์ใหม่เท่านั้น
Robby Cornelissen

1
หากไม่สามารถกำหนดเป้าหมาย "es6" ใน tsconfig และต้องใช้ Set with spread operator คุณจะทำอย่างไร?
Nate Getch

ประเด็นคือถ้าคุณใช้Array.from()คุณไม่จำเป็นต้องใช้ตัวดำเนินการกระจายอีกต่อไป มันเพิ่มค่าใช้จ่าย let uniques = Array.from(new Set([1, 2, 3, 1, 1]));
Robby Cornelissen


1

ใน Javascript:

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

ใน typescript:

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

ใน React State (setState):

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

0

เพื่อให้ใช้งานได้คุณต้องมี "target": "ES6" (หรือสูงกว่า) หรือ "downlevelIteration": true ใน compilerOptions ของ tsconfig.json ของคุณ สิ่งนี้ช่วยแก้ปัญหาของฉันและทำงานได้ดีหรือฉันหวังว่ามันจะช่วยคุณได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.