การใช้เนื้อหา › TypeScript
เอกสาร/การใช้เนื้อหา/TypeScript

TypeScript

หน้านี้สอนอะไร

type ของเอกสารสร้างจาก config โดยไม่ต้อง build อย่างไร จะตั้งชื่อ type ใช้ในโค้ดอย่างไร และจะสร้างไฟล์ type ให้แอปที่ import config ไม่ได้อย่างไร

ควรอ่านก่อน: Local API

สร้างจาก config

ประกาศ config ด้วย defineConfig ซึ่งเก็บ literal type ไว้ (slug, ชื่อ field, ตัวเลือกของ select) Local API จึงมี type โดยไม่ต้องรันขั้นตอน generate:

const cms = await getEasyCMS(config) // ใน Nuxt ใช้ useEasyCMS()
const { docs } = await cms.find('posts')
 
docs[0].title // string (required: true)
docs[0].excerpt // string | null | undefined (ไม่บังคับ)
docs[0].tags // ('vue' | 'nuxt')[] (select แบบ hasMany)
docs[0].author // number | User (relationship: id หรือเอกสารเมื่อ populate)
docs[0].status // 'draft' | 'published' (drafts: true)
 
await cms.find('pots') // error: ไม่มี collection นี้
await cms.create('posts', { titel: 'Hi' }) // error: ไม่มี field นี้ และขาด `title`

แต่ละ field กลายเป็น type อะไร:

FieldType
text, textarea, email, slug, datestring (date เป็น ISO 8601)
numbernumber
booleanboolean
selectunion ของตัวเลือก หรือ array ของตัวเลือกเมื่อใช้ hasMany
relationship, uploadid หรือเอกสารที่เกี่ยวข้องเมื่อ populate เป็น array เมื่อใช้ hasMany
groupobject ของ field ข้างใน
arrayarray ของแถวที่มี id และ field ของแถว
blocksarray ของแถว มี type หนึ่งแบบต่อหนึ่ง block แยกกันด้วย blockType
richTextเอกสารของ Tiptap
jsonunknown

field ที่ไม่มี required: true เป็นแบบไม่บังคับ คือเป็น null หรือไม่มีค่า ส่วน field ที่ hidden จะไม่อยู่ใน type

Blocks

แถวของ field แบบ blocks เป็น union ให้ตรวจ blockType เพื่อแยกประเภท:

for (const section of post.sections ?? []) {
  if (section.blockType === 'quote') section.author // เฉพาะแถว quote ที่มี author
}

field ที่ plugin เพิ่ม

plugin บอก type ว่าเพิ่มอะไร field ของ plugin จึงมี type เหมือน field ของคุณ

plugins: [
  seoPlugin({ collections: ['posts'] }),
  nestedDocsPlugin({ collections: ['pages'] }),
  redirectsPlugin({ collections: ['pages'] }),
]
 
post.meta.title // string | null | undefined
page.breadcrumbs[0]?.url // string | null | undefined
await findByPath(cms, 'pages', '/about') // Page | null
await cms.find('redirects') // collection ที่ plugin เพิ่ม

plugin ของคุณเองก็ทำแบบเดียวกันได้ด้วย definePlugin

ตั้งชื่อ type

import type { CollectionDocument, CreateInput, GlobalDocument, UpdateInput } from '@easy-cms/core'
import type config from './easy-cms.config'
 
export type Post = CollectionDocument<typeof config, 'posts'>
export type NewPost = CreateInput<typeof config, 'posts'>
export type PostChanges = UpdateInput<typeof config, 'posts'>
export type Site = GlobalDocument<typeof config, 'site'>

import type ทำให้ config (และ driver ของฐานข้อมูล) ไม่ถูกรวมเข้า bundle ฝั่ง browser component ก็ใช้ Post ได้

ใน Nuxt

server route คืนข้อมูลที่มี type และ useFetch ส่ง type ต่อไปให้หน้าเว็บ:

// server/api/posts.get.ts
export default defineEventHandler(async () => (await useEasyCMS()).find('posts'))
<script setup lang="ts">
const { data } = await useFetch('/api/posts') // data.value.docs เป็น Post[]
</script>

สร้างไฟล์ type สำหรับแอปอื่น

สำหรับ frontend ที่ import config ไม่ได้ เช่น แอป Vite ใน repo อื่นที่เรียก REST API:

npm
npx easy-cms generate:types              # เขียน easy-cms-types.ts
npx easy-cms generate:types --out ../web/src/cms.ts
pnpm
pnpm exec easy-cms generate:types              # เขียน easy-cms-types.ts
pnpm exec easy-cms generate:types --out ../web/src/cms.ts
yarn
yarn easy-cms generate:types              # เขียน easy-cms-types.ts
yarn easy-cms generate:types --out ../web/src/cms.ts
bun
bunx easy-cms generate:types              # เขียน easy-cms-types.ts
bunx easy-cms generate:types --out ../web/src/cms.ts

ไฟล์นี้ไม่มี import: มี interface หนึ่งตัวต่อ collection และ global พร้อม map Collections และ Globals

import type { Post } from './easy-cms-types'
 
const res = await fetch('/api/cms/posts?limit=10')
const { docs }: { docs: Post[] } = await res.json()

รันใหม่หลังเปลี่ยน config หรือใน CI เพื่อตรวจว่าไฟล์ยังตรงกับ config:

npm
npx easy-cms generate:types && git diff --exit-code easy-cms-types.ts
pnpm
pnpm exec easy-cms generate:types && git diff --exit-code easy-cms-types.ts
yarn
yarn easy-cms generate:types && git diff --exit-code easy-cms-types.ts
bun
bunx easy-cms generate:types && git diff --exit-code easy-cms-types.ts

ขั้นต่อไป

  • Local API: ทุกฟังก์ชันและตัวเลือก
  • REST API: ทำแบบเดียวกันผ่าน HTTP