API ฝั่งไคลเอนต์-เซิร์ฟเวอร์ที่ปลอดภัยต่อชนิดข้อมูลด้วย TypeScript?
ลองพิจารณาตัวอย่าง การใช้งาน getUser บนฝั่งผู้ใช้จะเป็นประมาณนี้
const user = await getUser(http, { id: '1' })
การทำงานที่ใช้ได้แต่ไม่ปลอดภัยต่อประเภทมากนัก
// ./api.ts - shared interfaces
const endpoint = '/users'
interface Arg { id: string }
interface Resp { name: string }
// ./client-api.ts - client side
import { endpoint, Arg, Resp } from './api.ts'
function getUser(http: HttpClient, arg: Arg): Promise<Resp> {
return http.get(endpoint, arg)
}
// ./server-api.ts - server side
import { endpoint, Arg, Resp } from './api.ts'
function getUser(db: Db, arg: Arg): Promise<Resp> {
return db.findById(arg.id)
}
// Additionally it needs to be registered
httpServer.on(endpoint, (params) => getUser(db, params))
ปัญหา: มีโค้ดซ้ำซ้อนมากเกินไป, มีความเป็นไปได้ที่จะจับคู่ Arg จากเมธอดหนึ่งกับ Resp ของอีกเมธอดหนึ่งผิด, หรือจับคู่ endpoint ผิด, หรือ ลืมลงทะเบียน endpoint บนเซิร์ฟเวอร์
การ ใช้งานที่ดีกว่า อาจเป็นแบบโค้ดด้านล่างนี้ แต่อย่างไรก็ตาม มันก็ยังไม่ได้บังคับให้ใช้ endpoint และมีโอกาสที่จะลืมลงทะเบียนตัวจัดการฝั่งเซิร์ฟเวอร์ได้:
// ./api.ts
interface GetUser {
endpoint: '/users',
arg: { id: string },
resp: { name: string }
}
type ClientFn<Command> = no idea how to do that, some TS magic
type ServerFn<Command> = no idea how to do that, some TS magic
// ./client-api.ts
const getUser: ClientFn<GetUser> = (http, arg) => http.get(endpoint, arg)
// ./server-api.ts
const getUser: ServerFn<GetUser> = (db, arg) => db.findById(arg.id)
httpServer.on(endpoint, (params) => getUser(db, params))
คุณรู้วิธี ที่ดีกว่า ในการทำสิ่งนั้นไหม? หรือ บางทีอาจมีไลบรารีสร้างโค้ด ใน TypeScript ที่สามารถทำสิ่งนั้นได้?