Skip to content

Commit

Permalink
blog add new content
Browse files Browse the repository at this point in the history
  • Loading branch information
mildronize committed Sep 15, 2023
1 parent 61da576 commit 94e33b3
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
title: Type-Safe Builder Pattern on TypeScript
---

Listen from TypeScript Meetup

```typescript
class Inventory<Items extends Record<string, unknown> = {}> {

items: Items = {} as Items;

add<NewItem extends Record<string, unknown>>(value: NewItem) {
this.items = {
...value as unknown as Items
}
return this as Inventory<Items & NewItem>;
}
}

const inventory = new Inventory()
.add({
hello: 'world',
}).add({
typescript: 5.1,
numbers: [23, '123']
});

console.log(inventory.items.typescript)


type A = typeof inventory.items;
// ^? type A = {
// hello: string;
// } & {
// typescript: number;
// numbers: (string | number)[];
// }
```
49 changes: 49 additions & 0 deletions contents/posts/2023-09-15-typecheck-schemas-on-existing-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: วิธีตรวจสอบให้ Zod schemas ตรงกับ Type ที่ประกาศไว้อยู่แล้ว
uuid: e6btvc1
tags:
- TypeScript
- Data Validation
- Zod
---

วันนี้เราจะมาพูดถึงวิธีการในการตรวจสอบความเข้ากันได้ระหว่าง [Zod](https://github.com/colinhacks/zod) Schema และ TypeScript อย่างสะดวกและรวดเร็ว ไอเดียดีๆ นี้มาจาก [@colinhacks](https://github.com/colinhacks) ซึ่งเป็นคนสร้าง Zod โดยการใช้ Zod และอยากแบ่งปันให้ทุกคน

โดยปกติแล้ว เราบ่งบอกประเภทของข้อมูลด้วย TypeScript เพื่อให้รู้ว่าข้อมูลที่เราใช้เป็นแบบไหน แต่ถ้าเราใช้ Zod Schema เพื่อทำการตรวจสอบข้อมูล มีวิธีหนึ่งที่จะทำให้เราสามารถตรวจสอบความเข้ากันได้ระหว่าง Zod Schema และ TypeScript ได้อย่างมีประสิทธิภาพ และเรียบง่าย นั่นคือการใช้ฟังก์ชัน `schemaForType` ตามตัวอย่างด้านล่าง:

```typescript
import { z } from 'zod';

type Dog = {
name: string
neutered: boolean
}


function schemaForType<TSchema>() {
return <TZodSchema extends z.ZodType<TSchema, any, any>>(arg: TZodSchema) => arg;
}

// ใช้งานได้ประมาณนี้:
const dog = schemaForType<Dog>()(
z.object({
// name: z.string(),
neutered: z.boolean(),
})
// ❌ Property 'name' is missing in type
// '{ neutered: boolean; }' but required in type 'Dog'
);
```

การทำงานของฟังก์ชันซ้อนกันนี้อาจดูแปลก ๆ แต่มันเป็นจำเป็น เพราะมีระดับการใช้ Generic สองระดับ

1. TypeScript ที่ต้องการ `TSchema`
2. Schema ที่สร้างขึ้นอย่างอัตโนมัติ `TZodSchema` ซึ่งถูก จำกัดโดย `extends z.ZodType<TSchema, any, any>`

อย่างไรก็ตาม คุณไม่ต้องกังวลเกี่ยวกับ `any` ที่เหลือสองตัวนั้น เนื่องจากเรากำลังใช้ `TSchema` เป็น Type hint โดยตรง นั่นหมายความว่าเราต้องใช้ฟังก์ชันเพิ่มเติมที่ให้เราสามารถตรวจสอบประเภทของ `TZodSchema` ได้ ซึ่งนี้เป็นเพราะ TypeScript จำเป็นต้องระบุพารามิเตอร์ Generic ทั้งหมดโดยชัดเจนหรือให้มันถูก Infer ทั้งหมด ไม่สามารถเลือกหรือผสมผสานได้ แม้ว่ามีข้อเสนอรองเรื่องนี้อยู่ [microsoft/TypeScript#26242](https://github.com/microsoft/TypeScript/issues/26242) ในเดียวนี้

ดังนั้น เราสามารตรวจสอบให้ Zod schemas ตรงกับ Type ที่ประกาศไว้อยู่แล้ว คุณสามารถใช้ฟังก์ชัน `schemaForType` เพื่อรักษาความ Consistency ในโปรเจคของคุณอีกด้วย! ขอบคุณที่ติดตามบทความนี้ครับและขอให้สนุกกับการเขียนโปรแกรมนะจ๊ะ

## Ref
- [colinhacks/zod Issuse#372](https://github.com/colinhacks/zod/issues/372#issuecomment-826380330)
- ใช้ ChatGPT ช่วยเรียบเรียงด้วย

0 comments on commit 94e33b3

Please sign in to comment.