การออกแบบ DSL สำหรับการสืบค้นแบบต่อเนื่อง
สร้าง API การสืบค้นที่ต่อคำสั่งได้และตรวจสอบตัวเอง
การออกแบบ DSL สำหรับการสืบค้นแบบต่อเนื่อง เป็นบทเรียน TypeScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน TypeScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
การออกแบบ Query DSL แบบต่อเนื่อง
เราออกแบบ Query DSL ที่ต่อการเรียกได้ โดยแต่ละขั้นตอนจะ ปรับให้ขั้นตอนถัดไปที่อนุญาตแคบลง ผ่านชนิดที่คืนกลับมา ผลลัพธ์อ่านได้คล้ายภาษาคำสั่งฐานข้อมูล และปฏิเสธลำดับที่ไม่ถูกต้องขณะคอมไพล์
ไวยากรณ์เป้าหมาย
เราต้องการลำดับดังนี้: from ตามด้วย where ที่เป็นตัวเลือกและเรียกซ้ำได้ จากนั้นจบด้วย select คุณไม่สามารถใช้ select ก่อน from และไม่สามารถใช้ from ซ้ำสองครั้ง
อินเทอร์เฟซสถานะ
จำลองแต่ละขั้นตอนเป็นอินเทอร์เฟซที่คืนค่าขั้นตอนถัดไป
interface Builder {
from(table: string): FromStage;
}
interface FromStage {
where(cond: string): FromStage; // repeatable
select(...cols: string[]): Result;
}
interface Result { sql: string; }การบังคับใช้ลำดับ
เนื่องจาก select มีอยู่เฉพาะบน FromStage การเรียกใช้กับ Builder เริ่มต้นจึงเป็นข้อผิดพลาดขณะคอมไพล์ ลำดับถูกบังคับใช้เพียงจากเมธอดที่แต่ละขั้นตอนเปิดให้ใช้
declare const db: Builder;
db.from("users").select("id"); // ok
db.select("id"); // Error: select missing on Builderการติดตามคอลัมน์ที่เลือก
เพิ่มเจเนอริกเสมือนเพื่อจดจำคอลัมน์ที่เลือกไว้ ทำให้ชนิดผลลัพธ์มีความแม่นยำ
interface FromStage<T extends string = never> {
where(c: string): FromStage<T>;
select<C extends string>(...cols: C[]): Result<C>;
}
interface Result<C extends string> { columns: C[]; }การปรับละเอียดในการเรียกแต่ละครั้ง
การเรียก where แต่ละครั้งสามารถสะสมข้อจำกัดไว้ในชนิดได้ด้วย ในตัวอย่างนี้เราทำให้เรียบง่าย แต่รูปแบบเดียวกันสามารถขยายไปใช้ติดตามพารามิเตอร์ที่ผูกไว้ได้
const q = db.from("users").where("age > 18").where("active = true");
// still FromStage; select remains availableการป้องกันการใช้ from ซ้ำ
เนื่องจาก FromStage ไม่เปิดให้ใช้ from คุณจึงไม่สามารถเรียกใช้ซ้ำสองครั้งได้ ไวยากรณ์จะห้ามไว้ในเชิงโครงสร้าง จึงไม่จำเป็นต้องมีตัวป้องกันขณะทำงาน
db.from("a").from("b"); // Error: from does not exist on FromStageขั้นตอนสิ้นสุด
select คืนค่า Result ซึ่งไม่เปิดให้ใช้ทั้ง where และ from จึงทำให้สายการเรียกสิ้นสุดลง เหลือเพียงการดำเนินการอ่านผลลัพธ์
const r = db.from("users").select("id", "name");
r.columns; // ("id" | "name")[]
// r.where(...) -> Error: where not on Resultข้อจำกัดคอลัมน์แบบมีชนิด
จำกัดคอลัมน์ให้ตรงกับแบบแผนของตารางที่รู้จักด้วยเจเนอริกอีกตัวหนึ่ง ทำให้คอลัมน์ที่ไม่รู้จักถูกปฏิเสธ และเชื่อม DSL นี้เข้ากับแนวคิดโออาร์เอ็มก่อนหน้า
interface Table<Cols extends string> {
select<C extends Cols>(...cols: C[]): Result<C>;
}
// db.from gives Table<"id" | "name" | "age">ขั้นตอนที่เป็นตัวเลือกกับขั้นตอนที่จำเป็น
ทำให้ขั้นตอนหนึ่งจำเป็นโดยเปิดให้ใช้เฉพาะเมธอดถัดไปหลังจากผ่านขั้นตอนนั้นแล้ว ตัวอย่างเช่น บังคับให้มี where อย่างน้อยหนึ่งครั้งด้วยการคืนค่าขั้นตอนที่มี select ปรากฏเฉพาะหลังจากเรียก where แล้ว ชนิดต่อเนื่องแบบเดียวกันนี้ยังสามารถอนุมาน ชนิดแถวผลลัพธ์ จากการดำเนินการคำสั่งสืบค้นได้ด้วย ทำให้ไวยากรณ์ขณะคอมไพล์เชื่อมโยงกับข้อมูลขณะทำงาน
เหตุใดเรื่องนี้จึงสำคัญ
DSL แบบต่อเนื่องที่ออกแบบเช่นนี้อธิบายตัวเองและใช้งานผิดได้ยาก ระบบเติมข้อความจะแสดงเฉพาะขั้นตอนถัดไปที่ถูกต้อง และลำดับที่ไม่ถูกต้องจะคอมไพล์ไม่ผ่าน นี่คือแกนหลักของไลบรารีตัวสร้างที่ใช้งานสะดวก
ตรวจสอบอย่างรวดเร็ว
ยืนยันความเข้าใจเกี่ยวกับการออกแบบ DSL แบบต่อเนื่อง
สรุปทบทวน
คุณออกแบบ Query DSL แบบต่อเนื่องให้เป็น เครื่องจักรสถานะระดับชนิด โดยอินเทอร์เฟซของแต่ละขั้นตอนจะคืนค่าขั้นตอนถัดไปและเปิดให้ใช้เฉพาะเมธอดที่ถูกต้อง เจเนอริกเสมือนใช้ติดตามคอลัมน์ที่เลือก ขั้นตอนสิ้นสุดใช้จบสายการเรียก และข้อจำกัดคอลัมน์ใช้ปฏิเสธชื่อที่ไม่รู้จัก ทั้งหมดนี้บังคับใช้ผ่านชนิดที่คืนกลับมา
คำถามที่พบบ่อย
บทเรียน “การออกแบบ DSL สำหรับการสืบค้นแบบต่อเนื่อง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การออกแบบ DSL สำหรับการสืบค้นแบบต่อเนื่อง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส TypeScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การออกแบบ DSL สำหรับการสืบค้นแบบต่อเนื่อง”
สร้าง API การสืบค้นที่ต่อคำสั่งได้และตรวจสอบตัวเอง คุณปฏิบัติ TypeScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน TypeScript Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน TypeScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “การออกแบบ DSL สำหรับการสืบค้นแบบต่อเนื่อง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน TypeScript Academy นี้ได้ไหม
ได้ บทเรียน TypeScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- DSL ระดับชนิดข้อมูลคืออะไร
- การออกแบบ DSL สำหรับการสืบค้นแบบต่อเนื่อง
- การตรวจสอบ input เวลาคอมไพล์
- ข้อความข้อผิดพลาดใน DSL ระดับชนิดข้อมูล