ทำให้การระงับข้อผิดพลาดของ Flow มีความเฉพาะเจาะจงมากขึ้น
เรากำลังปรับปรุงการระงับข้อผิดพลาดของ Flow เพื่อไม่ให้ซ่อนข้อผิดพลาดโดยไม่ได้ตั้งใจ
ในปีหน้า Flow กำลังวางแผนที่จะเปลี่ยนแปลงและปรับปรุงระบบประเภทต่างๆมากมาย อย่างไรก็ตามผลที่ตามมาประการหนึ่งคือคุณอาจต้องเพิ่มการระงับลงในโค้ดของคุณเนื่องจาก Flow จะค้นหาปัญหาที่มีอยู่ได้ดีขึ้น
ซึ่งอาจเป็นปัญหาได้เนื่องจากการระงับของ Flow ส่งผลมากกว่าข้อผิดพลาดเดิมที่คุณตั้งใจจะระงับ ซึ่งจะช่วยลดความสามารถของ Flow ในการตรวจจับข้อผิดพลาด นี่เป็นผลมาจากคุณสมบัติสองประการ: ประการแรกการระงับการไหลสามารถอยู่ที่ส่วนใดก็ได้ของข้อผิดพลาดประเภทและประการที่สองการระงับการไหลสามารถระงับข้อผิดพลาดประเภทใดก็ได้ ในการแก้ไขข้อบกพร่องเหล่านี้เราจะกำหนดให้วางการระงับไว้ที่ตำแหน่งในรหัสของคุณที่เกิดข้อผิดพลาดจริงและรวมถึงรหัสข้อผิดพลาดที่ระบุประเภทของข้อผิดพลาดที่คุณต้องการระงับ
เพื่อให้เข้าใจว่าทั้งหมดนี้หมายถึงอะไรเรามาดูลักษณะของข้อผิดพลาดประเภทของ Flow
ข้อผิดพลาดประเภทคืออะไร?
เมื่อ Flow พบปัญหาในขณะตรวจสอบโค้ดของคุณเช่นความเข้ากันไม่ได้ระหว่างสองประเภทหรือการเข้าถึงคุณสมบัติที่ไม่ถูกต้องจะสร้างข้อผิดพลาดที่รายงานให้ผู้ใช้ทราบอย่างแม่นยำว่ามีอะไรผิดปกติกับรหัสของพวกเขา ข้อผิดพลาดเหล่านี้อาจมีข้อมูลหลากหลายขึ้นอยู่กับสถานการณ์เฉพาะที่ทำให้เกิดข้อผิดพลาดแต่สองข้อที่เราให้ความสำคัญมากที่สุดคือประเภทของข้อผิดพลาดและตำแหน่งของข้อผิดพลาด ชนิดของข้อผิดพลาด encodes ลักษณะเฉพาะของพฤติกรรมที่ไม่ดีที่ตรวจพบการไหลในรหัสของคุณไม่ว่าจะเป็นสิ่งที่ง่ายเหมือนที่ผ่านการขัดแย้งมากเกินไปที่จะฟังก์ชั่นหรือบางสิ่งบางอย่างที่ซับซ้อนเช่นการแพร่กระจายชนิดสหภาพ ข้อมูลนี้จะบอก Flow ว่าจะแสดงข้อมูลประเภทใดให้กับผู้ใช้เพื่อให้อธิบายได้ดีที่สุดว่าคุณผิดพลาดตรงไหน สถานที่ของข้อผิดพลาดมีข้อมูลเกี่ยวกับข้อผิดพลาดที่ตั้งอยู่ในรหัสของคุณ มีสถานที่ตั้งสองประเภทที่อาจมีข้อผิดพลาดตำแหน่งหลัก (ซึ่งสามารถมีได้เพียงแห่งเดียว) และสถานที่รองซึ่งอาจมีได้หลายแห่งหรือไม่มีเลย ตำแหน่งหลักโดยประมาณสอดคล้องกับตำแหน่งในโค้ดของคุณที่เกิดข้อผิดพลาดจริงในขณะที่ตำแหน่งรองจะมีข้อมูลเกี่ยวกับไซต์คำจำกัดความของประเภทและค่าที่เกี่ยวข้องกับข้อผิดพลาด ตัวอย่างเช่น:
function foo(x : number) : void {}
foo("hello");
/* error */
foo("hello");
^ Cannot call `foo` with `"hello"` bound to `x` because string [1] is incompatible with number [2].
References:
2: foo("hello");
^ [1]
1: function foo(x : number) : void {}
^ [2]
function foo(x : number) : void {}
let y : string = "hello";
foo(y);
/* error */
foo(y);
^ Cannot call `foo` with `y` bound to `x` because string [1] is incompatible with number [2].
References:
2: let y : string = "hello";
^ [1]
1: function foo(x : number) : void {}
^ [2]
มีอะไรผิดปกติกับการปราบปราม?
เนื่องจากการระงับสามารถใช้ได้กับทั้งสถานที่หลักและรองการ//$FlowFixMe
แสดงความคิดเห็นเหนือคำจำกัดความของfoo
จะระงับข้อผิดพลาดในทั้งสองตัวอย่างข้างต้น เนื่องจากfoo
ปรากฏเป็นตำแหน่งรองในทุกข้อผิดพลาดที่ใช้จึงหมายความว่าการใช้งานใด ๆfoo
ที่ทำให้เกิดข้อผิดพลาดจะถูกระงับโดยการปราบปรามนี้ทุกที่ที่อาจเกิดขึ้น คุณสามารถโทรfoo
ด้วยอาร์กิวเมนต์ประเภทใดก็ได้และ Flow จะไม่แสดงข้อผิดพลาดหรือคำเตือนใด ๆ ให้คุณเกี่ยวกับสิ่งนี้ สิ่งนี้ทำให้ความเชื่อมั่นของผู้ใช้ลดลงในการตรวจสอบประเภทของ Flow และอนุญาตให้มีข้อบกพร่องที่อาจทำให้เกิดการผลิตได้
นอกจากนี้การระงับของ Flow จะส่งผลกระทบต่อข้อผิดพลาดทุกประเภทตราบเท่าที่มีตำแหน่งที่การปราบปรามครอบคลุม ซึ่งหมายความว่าสามารถระงับข้อผิดพลาดหลายประเภทได้โดยการปราบปรามเพียงครั้งเดียว หากต้องการดูอันตรายในสิ่งนี้ให้พิจารณาตัวอย่างต่อไปนี้:
// library file lib.js
function foo(x : number) : void {}
// impl file
const {foo} = require("lib.js");
let y : string = "hello";
// $FlowFixMe
foo(y);
เราจะทำอย่างไรกับเรื่องนี้?
เพื่อแก้ไขปัญหานี้เราจะทำการเปลี่ยนแปลงต่อไปนี้:
- บังคับใช้สถานที่หลัก เราจะเปลี่ยนพฤติกรรมการปราบปรามเพื่อให้การปราบปรามใช้กับข้อผิดพลาดเมื่อวางไว้ที่ตำแหน่งหลักเท่านั้น ตัวอย่างเช่นแทนที่จะอนุญาตให้คุณระงับการโทรที่ไม่ถูกต้องตามคำจำกัดความของฟังก์ชันตอนนี้เราต้องการให้การปราบปรามอยู่ที่ไซต์การโทรเอง วิธีนี้ Flow จะยังคงสามารถแจ้งเตือนคุณเกี่ยวกับการเรียกฟังก์ชันอื่น ๆ ที่อาจไม่ถูกต้องได้
- เพิ่มรหัสข้อผิดพลาด นอกจากนี้เราจะเพิ่มรหัสข้อผิดพลาดในการปราบปรามของเราดังนั้นจึงระงับเฉพาะข้อผิดพลาดประเภทที่ระบุเท่านั้น วิธีนี้จะป้องกันการระงับจากการระงับข้อผิดพลาดที่คุณไม่คาดคิดโดยไม่คาดคิด
- สร้างมาตรฐานไวยากรณ์การปราบปราม ก่อนหน้านี้ไวยากรณ์ที่ยอมรับได้สำหรับการระงับข้อผิดพลาดสามารถกำหนดค่าได้ด้วยตนเองใน
.flowconfig
สำหรับโปรเจ็กต์ที่กำหนดทำให้ไวยากรณ์การปราบปรามที่ไม่สอดคล้องกันระหว่างโปรเจ็กต์ จากการเปลี่ยนแปลงข้างต้นเราจะกำหนดมาตรฐานของไวยากรณ์การปราบปราม รองรับเฉพาะรูปแบบ$FlowFixMe[incompatible-type]
หรือ$FlowExpectedError[incompatible-type]
การเปิดตัว
เราตระหนักดีว่าการเปลี่ยนแปลงนี้อาจทำให้ข้อผิดพลาดจำนวนมากในฐานรหัสของคุณไม่ถูกต้องโดยเฉพาะอย่างยิ่งหากคุณมีนิสัยชอบวางการระงับในโค้ดไลบรารี เพื่อลดภาระนี้เรามีคำแนะนำสองสามข้อ:
- หากต้องการย้ายการปราบปรามที่เพิ่งไม่ถูกต้องไปยังตำแหน่งหลักเราขอแนะนำให้ใช้ยูทิลิตี้
add-comments
และremove-comments
ยูทิลิตี้ที่มีให้ในเครื่องมือโฟลวร่วมกัน การเรียกใช้./tool remove-comments
จะลบความคิดเห็นที่ไม่ระงับข้อผิดพลาดอีกต่อไปเนื่องจากไม่ได้อยู่ในตำแหน่งหลักและ./tool add-comments
จะทำการระงับใหม่ในตำแหน่งที่ไม่ได้รับการสนับสนุน./tool
สคริปต์สามารถเข้าถึงได้โดยการโคลนที่เก็บกระแสบน GitHub - การปราบปรามโดยไม่มีรหัสข้อผิดพลาดจะยังคงระงับข้อผิดพลาดใด ๆ และทั้งหมดในตำแหน่งของพวกเขา แต่เมื่อเราเปิดตัวคุณลักษณะรหัสข้อผิดพลาดคุณสามารถเพิ่มรหัสที่เหมาะสมลงในโค้ดเบสของคุณผ่านกระบวนการที่คล้ายกันดังที่กล่าวมาข้างต้น การลบความคิดเห็นเก่าทั้งหมดของคุณและเพิ่มเข้าไปใหม่
add-comments
จะรวมรหัสข้อผิดพลาดในความคิดเห็นที่เพิ่มเข้ามาใหม่