1 คะแนน โดย GN⁺ 2025-12-16 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • PR รีแฟกเตอร์ ของคลังเก็บ Svelte ในปี 2023 ที่เปลี่ยนไปใช้โค้ดแบบอิง JSDoc ได้รับความสนใจจากกลุ่มที่ตั้งข้อกังขาต่อ TypeScript
  • ฝั่ง Svelte อธิบายว่านี่ไม่ใช่จุดยืนแบบ ต่อต้าน TypeScript แต่เป็นส่วนหนึ่งของการ พึ่งพา TypeScript อย่างต่อเนื่อง
  • บทความนี้ไม่ได้มอง JSDoc กับ TypeScript เป็นคู่ตรงข้าม แต่เน้นว่า ตัว JSDoc เองก็เป็นส่วนหนึ่งของ TypeScript
  • TypeScript ทำหน้าที่เป็น เอนจิน IntelliSense ซึ่งรับผิดชอบทั้งการตีความคอมเมนต์ JSDoc และฟีเจอร์เติมโค้ดอัตโนมัติ
  • JSDoc ให้ ความสามารถในการวิเคราะห์แบบสแตติกในระดับเดียวกัน โดยไม่ต้องมีขั้นตอน build และในโปรเจ็กต์ JavaScript ยุคใหม่ก็ทำหน้าที่แทบไม่ต่างจาก TypeScript

เบื้องหลัง PR ของ Svelte และประเด็นถกเถียง

  • เดือนพฤษภาคม 2023 PR รีแฟกเตอร์ภายใน ของคลังเก็บ Svelte ขึ้นไปอยู่หน้าแรกของ Hacker News
    • PR นี้เป็นการย้ายการประกาศชนิดในไฟล์ .ts ไปไว้ใน คอมเมนต์ JSDoc ของไฟล์ .js
    • บางส่วนตีความว่านี่เป็นการปฏิเสธข้อดีของ TypeScript
  • ผู้ก่อตั้ง Svelte อย่าง Rich Harris ได้อธิบายด้วยตนเองบน HN ว่า “นี่ไม่ใช่การต่อต้าน TypeScript”
    • เขาระบุด้วยว่า ความมุ่งมั่นของ Svelte ต่อ TypeScript ยังคงแข็งแกร่ง
  • หลังเหตุการณ์นี้ มีบทความเปรียบเทียบ “TypeScript vs JSDoc” จำนวนมากตามมา และแนวคิดที่มอง JSDoc ว่าเป็น “TypeScript ที่ไม่มีขั้นตอน build” ก็เริ่มแพร่หลาย

ต้นกำเนิดและแก่นแท้ของ TypeScript

  • ช่วงปลายทศวรรษ 2000 ถึงต้นทศวรรษ 2010 JavaScript ถูกมองว่าเป็นภาษาที่ขาด การเติมโค้ดอัตโนมัติและความปลอดภัยของชนิดข้อมูล
    • นักพัฒนาของ Microsoft รับมือด้วยการใช้ ScriptSharp แปลงโค้ด C# เป็น JS
  • จากภูมิหลังนี้จึงเกิด TypeScript ซึ่งโดยแก่นแท้แล้วเริ่มต้นจากการเป็น เครื่องมือ build เพื่อปรับปรุงการพัฒนา JS

TypeScript คือ IntelliSense

  • TypeScript ไม่ได้เป็นเพียงภาษา แต่ยังทำหน้าที่เป็น เอนจิน IntelliSense
    • แม้จะไม่ได้ใช้ไฟล์ .ts ฟีเจอร์อย่างการเติมโค้ดอัตโนมัติ ข้อมูลพารามิเตอร์ และการค้นหาสัญลักษณ์ ก็ยังมาจากบริการภาษาของ TypeScript
    • ในเอดิเตอร์ส่วนใหญ่ แม้ตอนเขียนโค้ด JS ก็มี บริการของ TypeScript ทำงานอยู่เบื้องหลัง

TypeScript คือ JSDoc

  • บริการภาษาของ TypeScript ยังถูกใช้ในการ ตีความคอมเมนต์ JSDoc ด้วย
    • ใน CHANGELOG ของ TypeScript มักมีรายการเพิ่มฟีเจอร์ที่เกี่ยวข้องกับ JSDoc อยู่เสมอ
    • โปรเจ็กต์ที่อิง JSDoc ก็สามารถตั้งค่าผ่าน tsconfig.json ได้ และใช้คำสั่ง tsc เพื่อ ตรวจสอบชนิดข้อมูล ได้
  • ดังนั้น นักพัฒนาที่ใช้ JSDoc อยู่ก็เท่ากับว่า กำลังใช้ TypeScript อยู่แล้ว

ประสบการณ์กับโปรเจ็กต์ที่อิง JSDoc

  • ผู้เขียนเล่าประสบการณ์การเขียนฟรอนต์เอนด์ของโปรเจ็กต์เดิมใหม่โดย อิงคำอธิบายชนิดด้วย JSDoc
    • ยกเว้นฟีเจอร์รันไทม์อย่าง enum แล้ว รูปแบบการแสดงชนิดส่วนใหญ่ของ TypeScript สามารถทำได้ด้วย JSDoc
    • แม้ generic จะมีไวยากรณ์ที่ซับซ้อนกว่าเล็กน้อย แต่ก็ทำให้ต้องใช้การอนุมานชนิดอย่างเต็มที่มากขึ้น
  • ในโปรเจ็กต์ JSDoc เมื่อคลิกฟังก์ชันก็สามารถ ไปยังโค้ดจริงได้ทันที ทำให้ประสบการณ์พัฒนาดีขึ้น
  • ระบบนิเวศเครื่องมือของ TypeScript ยังนำมาใช้ซ้ำกับโปรเจ็กต์ JSDoc ได้
    • เช่น ไลบรารีที่สร้างชนิดจากสคีมา OpenAPI หรือ GraphQL ก็สามารถ สร้างชนิดในรูปคอมเมนต์ JSDoc ได้

บทสรุปและกรณีเพิ่มเติม

  • JSDoc ไม่ใช่ทางเลือกแทน TypeScript แต่ ใช้ระบบการวิเคราะห์แบบสแตติกชุดเดียวกัน
    • แม้จะตัดขั้นตอน build ออกไป แต่ก็ยังให้ ความปลอดภัยของชนิดข้อมูลในระดับเทียบเท่า
  • นอกจากนี้ยังมีการกล่าวถึงกรณีที่ โปรเจ็กต์ webpack ย้ายมาใช้ JSDoc เช่นกัน
  • ในฐานะผู้เชี่ยวชาญด้าน TypeScript ผู้เขียนจึงประกาศจุดยืนอย่างชัดเจนว่า “JSDoc คือ TypeScript

1 ความคิดเห็น

 
GN⁺ 2025-12-16
ความคิดเห็นจาก Hacker News
  • ได้สรุปสิ่งที่เรียนรู้จากการพัฒนาและบำรุงรักษาซอฟต์แวร์เว็บและหุ่นยนต์ด้วย Python/JavaScript มาหลายปี
    ประเภทข้อมูลมีอยู่เสมอแม้จะไม่ได้ระบุไว้ และถ้าไม่ระบุ สุดท้ายมันก็จะมีอยู่แค่ในหัว
    แต่ความจำของคนนั้นเลือนหายได้ง่าย และคนอื่นก็เข้าถึงได้ยาก
    ดังนั้น การใส่ type คือวิธีทำเอกสารที่ยอดเยี่ยม
    JSDoc และ TypeScript เป็นรูปแบบมาตรฐานในการแสดง type และทั้งคู่ก็มีข้อดีข้อเสีย
    สิ่งสำคัญคือการนิยาม type ให้สม่ำเสมอและคาดเดาได้
    ตัวตรวจสอบ type คือวิธีที่คอมพิวเตอร์พูดว่า “งั้นก็พิสูจน์มา”
    ไม่ใช่ว่าทุกโปรแกรมจะต้องการการพิสูจน์ในระดับเดียวกัน และการพิสูจน์มากเกินไปก็อาจเป็นความสูญเปล่า
    เพราะงั้นฉันจึงชอบภาษาที่ “พิสูจน์ได้” เท่าที่จำเป็น

    • เห็นด้วยเต็มที่กับประโยคที่ว่า “ข้อมูลที่มีอยู่แค่ในหัวนั้นเลือนหายได้ง่าย”
      โดยเฉพาะอย่างยิ่ง ‘คนอื่น’ นั้นรวมถึงตัวเราเองในอนาคตด้วย ซึ่งเป็นสิ่งที่ได้เรียนรู้อย่างหนักแน่นจากการทำงาน
    • Rust เป็นที่รู้จักว่าเป็นตัวแทนของแนวคิด “prove it” แต่ฉันคิดว่าในความเป็นจริงไม่ได้เป็นแบบนั้น
      Rust สามารถผ่อนข้อจำกัดได้ด้วยวิธีอย่าง unsafe, Arc, clone แต่ต้องแลกกับการเลือกอย่างชัดเจนว่าข้อจำกัดใดที่ยังไม่ได้รับการพิสูจน์
      ในทางกลับกัน ภาษาที่ “ไม่ต้องพิสูจน์” มักทำให้ยากที่จะรู้ว่าเบื้องในใช้แนวทางไหน
      แนวทางของ Rust ทำให้ช่วงแรกสามารถเขียนแบบหลวม ๆ คล้าย Python ได้ แต่ต่อมาจะได้เปรียบมากกว่ามากในด้าน ความอ่านง่ายและการขยายระบบ
    • เห็นด้วยว่า JSDoc และ TypeScript มีจุดมุ่งหมายเดียวกัน
      ไม่ได้มีเจตนาจะเชียร์เครื่องมือใดเป็นพิเศษ แค่อยากเน้นว่าทั้งคู่ต่างก็เป็น วิธีแสดงออกของระบบ type
    • ได้เรียนรู้บทเรียนนี้ตั้งแต่สมัยเรียนมหาวิทยาลัยเมื่อ 25 ปีก่อนแล้ว
      ภาษาที่มี static typing จัดการได้ง่ายกว่ามากในโปรเจกต์ทีม และจนถึงตอนนี้ถ้าเลือกได้ก็ยังชอบ static type
    • เห็นด้วยกับประโยคที่ว่า “type มีอยู่เสมอ” แต่ภาษาที่ต้องระบุ type อย่าง C# ต้องใช้แรงมากกว่า Ruby อย่างเห็นได้ชัด
      ถ้าดู type definition ของ TypeScript ที่ถูกเพิ่มเข้ามาทีหลังให้กับไลบรารี JS เดิม จะเห็นว่าความซับซ้อนสูงมาก
      type ที่ผิดแค่จุดเดียวก็ทำให้คอมไพล์ทั้งชุดพังได้
      สุดท้ายแล้ว ภาษาที่เป็น dynamic ก็ต้องใช้แบบ ‘รับผิดชอบด้วยตัวเอง’
  • ฉันชอบทุกอย่างที่ทำด้วย JavaScript ได้โดย ไม่ต้องมี build step
    การผสมกันของ HTML/CSS สมัยใหม่, Web Components และ JSDoc นั้นถูกประเมินค่าต่ำเกินไป
    มันอาจไม่เหมาะกับทุกคน แต่ฉันคิดว่ามันเป็นตัวเลือกของสแตกฟรอนต์เอนด์ที่ทันสมัยเพียงพอ

    • ตอนนี้ตั้งแต่ Node 24 เป็นต้นไป TypeScript ก็รันได้โดยไม่ต้องมี build step แล้ว
    • เข้าใจเสน่ห์ของแนวทางที่ไม่มี build step แต่ในทางปฏิบัติการจัดการ dependency กลับซับซ้อนขึ้น
      และด้วยฟีเจอร์อย่าง HMR ต้นทุนของ build step ก็ลดลงไปมากแล้ว
    • ตลอด 10 ปีที่ผ่านมาไม่เคยเขียนโค้ด JS ที่ deploy จริงโดยตรงเลย
      เพราะต้องผ่าน Vite หรือ Webpack ตลอด จึงไม่ค่อยรู้สึกถึงข้อดีของ JS แบบไม่มี build
    • Web Components สร้างแล้วค่อนข้างทรมาน
      อยากให้มีวิธีที่ทำคอมโพเนนต์ซับซ้อนได้ง่ายกว่านี้
    • ข้อดีของการใช้ HTML+CSS+JSDoc คือ การผสานกับ browser developer tools ได้อย่างเป็นธรรมชาติ
      ไม่ว่าจะเป็นการตามดู network request, กระโดดไปยังซอร์สโค้ดโดยตรง, ตั้ง breakpoint ฯลฯ การดีบักทำได้ตรงไปตรงมามากกว่า
      ยิ่งระบบใหญ่ขึ้น สภาพแวดล้อมแบบนี้ก็ยิ่งช่วยได้มาก
  • ในยุคที่ SPA กำลังบูม JSDoc คือผู้กอบกู้ของการจัดการ type
    หลังจากนั้น Google Closure Compiler ก็ปรากฏขึ้นและมอบ type safety บนฐานของ JSDoc ส่วน TypeScript ก็รองรับ (TS)JSDoc พร้อมไวยากรณ์ของตัวเอง
    สุดท้ายชุมชนก็เลือก TypeScript และ Closure Compiler ก็เลือนหายไป
    เพราะงั้น (TS)JSDoc จึงกลายเป็น โบราณวัตถุจากยุคที่ MS แข่งกับ Google
    ตอนนี้ TS มีฟีเจอร์มากกว่ามาก เช่น generics, Enum, utility types, การทดสอบ type ของ Vitest, type guards ฯลฯ
    ฉันใช้ทั้ง TS และ JSDoc ร่วมกัน — TS สำหรับโค้ด, JSDoc สำหรับเอกสาร (@link, @see, @deprecated, @example เป็นต้น)

    • ที่จริงแล้ว JSDoc ยุคใหม่ใช้ TypeScript language service
      ฟีเจอร์ TS ส่วนใหญ่ เช่น generics, utility types, type guards, การพาร์ส regular expression ฯลฯ ใช้ใน JSDoc ได้เหมือนกัน
      ฉันเคยลองทำในโปรเจกต์ส่วนตัวด้วย JSDoc ล้วนทั้งหมดรวมถึง generics ด้วย
    • ข้ออ้างข้างบนไม่เป็นความจริง
      การบอกว่า (TS)JSDoc เป็นของตกยุคคือ ข้อมูลผิด จึงไม่ควรเผยแพร่โดยไม่ตรวจสอบ
    • บทความนี้เองก็คือ คำโต้แย้งโดยตรง ต่อคำกล่าวนั้น
  • หลายคนบอกว่ามี type จำนวนมากที่แสดงด้วย JSDoc ไม่ได้ แต่ฉันคิดว่าคงจะดีถ้ามันทำแบบทั้งภาษาได้เหมือน Flow
    TypeScript เองก็ทำแบบนั้นได้ แต่ไม่รู้ว่าทำไมถึงไม่ทำ

    • ถ้ามีตัวอย่างที่ชัดเจนก็อยากฟัง
      ฉันเองก็เคยคิดแบบนั้นมาก่อน แต่พอรีแฟกเตอร์โปรเจกต์ให้เป็น JSDoc แล้วก็เปลี่ยนความคิด
      ใน JSDoc ก็สามารถนิยาม generic slot ได้ด้วย @template
      ตัวอย่าง:
      /** @type {ReturnType<typeof useState<Book[]>>} */
      const [books, setBooks] = useState();
      
    • ตอนนี้แทบทุก ฟีเจอร์ของระบบ type ถูกเพิ่มเข้ามาในไวยากรณ์ JSDoc แล้ว
    • ระบบ type ของ TypeScript นั้น Turing complete จึงมีพลังในการแสดงออกแทบไร้ขีดจำกัด
      ลิงก์ที่เกี่ยวข้อง
  • แพ็กเกจที่เขียนด้วย JSDoc มีประสบการณ์ใช้งานที่ดีเพราะ กด CMD/CTRL แล้วไปยังโค้ดจริงได้

    • เรื่องนี้ปรับแต่งได้ด้วยการตั้งค่า editor เช่นกัน
    • จริง ๆ แล้วใน TypeScript ก็ทำงานเหมือนกัน
  • เมื่อ 5 ปีก่อนในงาน meetup มีวิทยากรคนหนึ่งพูดว่า “ถ้าไม่ชอบ TypeScript, JSDoc ก็เป็นทางเลือกได้”
    ฉันอธิบายไปว่าจริง ๆ แล้ว ทั้งคู่ก็คือ TypeScript เหมือนกัน แต่หัวหน้าของฉันไม่เชื่อ

    • ฉันคิดว่าความต่างอยู่ที่ระดับของ การบีบอัดไวยากรณ์ (syntax compression)
    • คำพูดที่ว่า “JSDoc สุดท้ายก็คือ TypeScript” นั้นถูกแค่ครึ่งเดียว
      JSDoc กับ TS ต่างก็เป็นการแสดง type แบบชัดเจนเหมือนกัน แต่ ไวยากรณ์ของ TS ทรงพลังยิ่งกว่า
      ถึงอย่างนั้น สำหรับคนที่อยากคงสภาพแวดล้อม JS ไว้พร้อมได้ประโยชน์จากเครื่องมือด้าน type, JSDoc ก็เป็นทางเลือกที่ดี
  • อีกมุมหนึ่งคือ JSDoc ไม่ใช่ TypeScript
    type ที่นิยามด้วย @typedef จะถูก export อัตโนมัติ และไม่มีวิธีควบคุมเรื่องนี้
    ประเด็นที่เกี่ยวข้อง
    เพราะเหตุนี้เวลาพัฒนาไลบรารี IntelliSense จึงแสดงผลรก ๆ ออกมา จนใช้งานลำบาก

    • JSDoc ค่อนข้างเข้ากับ Web Components ได้ดี
      แค่คัดลอกไฟล์ “my-component.js” ไปตรง ๆ ก็ทำงานได้โดยไม่ต้อง build
      แต่ถ้าเป็นโปรเจกต์ใหญ่ ฉันชอบไวยากรณ์ TS มากกว่า
    • ในเชิงเทคนิคเป็นข้อสังเกตที่ถูกต้อง แต่ถ้า ปรับ @import ก็แก้ได้เกือบทั้งหมด
  • เห็นด้วยกับคำกล่าวที่ว่า “JSDoc ไม่ใช่ทางเลือกแทน TypeScript”
    JSDoc ก็ ให้การวิเคราะห์แบบ static ได้ แต่ไม่มี build step
    ดู เอกสารทางการของ Node

    • ภายในยังคงมี build step อยู่ดี
      แต่ TypeScript ที่อิง JSDoc ใช้งานในเบราว์เซอร์ได้ด้วย
      ส่วนตัวฉันชอบ ความอ่านง่ายของไวยากรณ์ TS และการลบ type ด้วยเครื่องมืออย่าง swc ก็เร็วพออยู่แล้ว
    • แต่ฟีเจอร์นี้ จำกัดอยู่ในสภาพแวดล้อม Node และใช้ในเบราว์เซอร์ไม่ได้
  • เหตุผลที่ TypeScript ชนะทางเลือกอื่นทั้งหมดได้ก็เพราะมัน ยังคงเป็น type checker ไม่ใช่ภาษาใหม่
    ช่วงแรกทิศทางอาจแกว่งไปบ้าง แต่ก็ปรับได้เหมาะสม และตอนนี้ในโค้ดส่วนใหญ่แทบไม่ได้ใช้ enums กันแล้ว

  • ใน VSCode ถ้าเปิดการตั้งค่า “TypeScript: Prefer Go To Source Definition” ก็จะกระโดดไปยังซอร์สจริงได้
    และถ้าเพิ่ม declarationMap: true ใน tsconfig ก็จะทำงานได้แม่นยำขึ้น
    ฉันแทบจะชอบให้ cmd+click แล้วเห็นซอร์ส อยู่เสมอ