5 คะแนน โดย asheswook 2025-12-24 | 2 ความคิดเห็น | แชร์ทาง WhatsApp

สวัสดีครับ

โดยทั่วไปแล้ว หากพัฒนาแบ็กเอนด์ด้วย Typescript จุดที่มักเกิดข้อผิดพลาดบ่อยคือส่วนของ รันไทม์ ที่ไม่สามารถตรวจจับได้ในช่วงคอมไพล์ไทม์

ยกตัวอย่างเช่น implementation ของ repository ที่ใช้แปลง DB row หรือ ส่วนที่สื่อสารกับ API ภายนอก ซึ่งเป็นจุดที่เกิดบ่อยที่สุด

เช่น ค่าที่รับมาจาก DB อาจต่างจากที่คาดไว้ ทำให้มีการใส่ค่า undefined เข้าไปในรันไทม์ หรือในตอนทำ casting ก็อาจตีความค่าพื้นฐานที่มาจากภายนอกผิดพลาดจนเกิด human error ได้

แม้แต่ตอน implement repository ก็ต้องคอยเขียน type สำหรับค่าพื้นฐานที่มาจากภายนอกด้วย interface แบบแปะเพิ่มไปเรื่อย ๆ แม้อาจเป็นปัญหาเล็กน้อย แต่ผมเลยทำตัวนี้ขึ้นมาเพื่อให้ใช้งานได้สะดวกขึ้น

ในการใช้งานจริง ทั้งโค้ดส่วน API ภายนอกและ implementation ของ DB กระชับขึ้นมาก และ ข้อผิดพลาดที่เกิดในรันไทม์ก็ลดลงด้วย

หลังจากทีมลองใช้กับแบ็กเอนด์แล้วรู้สึกว่าใช้ได้ดี จึงนำขึ้นเผยแพร่บน npm

import { validate } from 'valdex';  
  
const data: unknown = await fetchData();  
  
validate(data, {  
  name: String,  
  age: Number,  
  active: Boolean  
});  
  
// TypeScript now knows the exact type of data  
data.name // string  
data.age // number  
data.active // boolean  

ตัวอย่างข้างต้นสมมติสถานการณ์ที่ดึงข้อมูลมาจากภายนอก ไม่ว่าจะใช้ axios, mysql2 หรือ postgres pg ก็สามารถนำไปใช้ได้ โดยจะทำการตรวจสอบค่าที่เข้ามาในรูปแบบ unknown และหากถูกต้อง ใน control flow หลังจากนั้นค่านั้นจะถูก assertion (asserts) ให้เป็นค่าตามที่กำหนดไว้ใน validate()

แน่นอนว่าคุณอาจเลือกใช้ไลบรารีอย่าง zod ก็ได้

แต่สิ่งที่แตกต่างกันระหว่าง zod กับ valdex คือ valdex ไม่ได้สร้าง schema เป็น instance เพื่อใช้งาน แต่สามารถจัดการประเภทข้อมูลแบบ declarative ได้ภายในจุดที่รับข้อมูลมาเลย จึงไม่จำเป็นต้องคอยเลื่อนขึ้นลงไปแก้ interface หรือแก้คลาส DTO เพื่อปรับโค้ดอีกต่อไป

npm i valdex  

สามารถติดตั้งผ่าน npm แล้วลองใช้งานได้

Github: https://github.com/asheswook/valdex

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

 
sunrabbit 2025-12-24

ถ้าเป็นแค่ประเภทข้อมูลแบบง่าย ๆ ก็น่าจะให้ DX ที่ดีมากเลยล่ะ โอ้โห

 
asheswook 2025-12-24

รองรับทั้ง Nested Object และ Array เลยทำให้จนถึงตอนนี้ยังไม่มีส่วนไหนที่ติดขัดน่ารำคาญเวลาใช้งานกับ API ภายนอกหรือทำ implementation ของรีโพซิทอรีครับ
ขอบคุณที่ให้ความสนใจครับ!