Skip to content

Schema 类型系统

farrow-schema 提供了完整的类型系统,让你能够精确描述数据结构。

🧱 基础类型

标量类型

typescript
import { String, Number, Boolean, Date, ID } from 'farrow-schema'

class Profile extends ObjectType {
  id = ID           // string (非空)
  name = String     // string
  age = Number      // number
  active = Boolean  // boolean
  createdAt = Date  // Date
}

数值类型

typescript
class Product extends ObjectType {
  price = Number      // 任意数字
  quantity = Int      // 整数(验证时会检查)
  rating = Float      // 浮点数
}

可选与可空

typescript
import { Optional, Nullable } from 'farrow-schema'

class Article extends ObjectType {
  title = String
  bio = Optional(String)      // string | undefined(字段可省略)
  content = Nullable(String)  // string | null(必须提供字段)
}

// 使用示例
const data1 = { title: 'Hello' }                     // ✅ bio 可省略
const data2 = { title: 'Hello', bio: undefined }     // ✅
const data3 = { title: 'Hello', content: null }      // ✅ content 显式为 null

Optional vs Nullable

  • Optional(T)T | undefined,字段可省略
  • Nullable(T)T | null,字段必须存在,但值可以是 null

复合类型

列表类型

typescript
import { List } from 'farrow-schema'

class Blog extends ObjectType {
  tags = List(String)              // string[]
  scores = List(Number)            // number[]
  comments = List(Comment)         // Comment[](嵌套对象)
}

键值对类型

typescript
import { Record } from 'farrow-schema'

class Config extends ObjectType {
  labels = Record(String)    // { [key: string]: string }
  counters = Record(Number)  // { [key: string]: number }
}

元组类型

typescript
import { Tuple } from 'farrow-schema'

class Geometry extends ObjectType {
  point = Tuple(Number, Number)                 // [number, number]
  rgb = Tuple(Number, Number, Number)           // [number, number, number]
  mixed = Tuple(String, Number, Boolean)        // [string, number, boolean]
}

对象类型

基础对象

typescript
class User extends ObjectType {
  id = String
  name = String
  email = String
}

type UserType = TypeOf<typeof User>
// {
//   id: string
//   name: string
//   email: string
// }

嵌套对象

使用对象字面量定义嵌套结构:

typescript
class User extends ObjectType {
  id = String
  name = String
  profile = {
    bio: String,
    avatar: Optional(String),
    social: {
      twitter: Optional(String),
      github: Optional(String)
    }
  }
}

type UserType = TypeOf<typeof User>
// {
//   id: string
//   name: string
//   profile: {
//     bio: string
//     avatar?: string
//     social: {
//       twitter?: string
//       github?: string
//     }
//   }
// }

递归引用

ObjectType 的核心优势:支持自引用和相互引用

typescript
// 自引用 - 树形结构
class Comment extends ObjectType {
  id = String
  content = String
  replies = List(Comment)        // ✅ 支持自引用
  parent = Optional(Comment)     // ✅ 可选自引用
}

// 相互引用
class Post extends ObjectType {
  title = String
  author = User                  // 引用 User
}

class User extends ObjectType {
  name = String
  posts = List(Post)             // 引用 Post,形成循环引用
}

Struct - 快速定义结构

适用场景

  • 在联合类型中定义变体
  • 运行时动态构建 Schema
  • 快速定义简单结构

限制:不支持递归引用

typescript
import { Struct } from 'farrow-schema'

// 基础用法
const UserStruct = Struct({
  id: String,
  name: String,
  age: Number
})

type UserType = TypeOf<typeof UserStruct>
// { id: string, name: string, age: number }

在联合类型中使用(推荐场景):

typescript
import { Union, Literal } from 'farrow-schema'

const APIResult = Union(
  Struct({
    success: Literal(true),
    data: List(User)
  }),
  Struct({
    success: Literal(false),
    error: String
  })
)

type APIResultType = TypeOf<typeof APIResult>
// { success: true, data: User[] } | { success: false, error: string }

ObjectType vs Struct

特性ObjectTypeStruct
定义方式class 继承函数调用
递归引用✅ 支持❌ 不支持
适用场景复杂业务模型、树形结构联合类型变体、动态构建
推荐度通用推荐特定场景

联合与字面量类型

字面量类型

typescript
import { Literal } from 'farrow-schema'

// 单个字面量
const StatusActive = Literal('active')
const HttpOK = Literal(200)

联合类型

typescript
import { Union } from 'farrow-schema'

// 枚举值
const Status = Union(
  Literal('draft'),
  Literal('published'),
  Literal('archived')
)

type StatusType = TypeOf<typeof Status>
// 'draft' | 'published' | 'archived'

判别联合(推荐模式)

使用 type 字段作为判别符:

typescript
const Payment = Union(
  Struct({
    type: Literal('credit_card'),
    cardNumber: String,
    cvv: String
  }),
  Struct({
    type: Literal('paypal'),
    email: String
  }),
  Struct({
    type: Literal('crypto'),
    wallet: String,
    network: String
  })
)

type PaymentType = TypeOf<typeof Payment>

// TypeScript 自动类型窄化
function processPayment(payment: PaymentType) {
  switch (payment.type) {
    case 'credit_card':
      console.log(payment.cardNumber) // ✅ 类型安全
      break
    case 'paypal':
      console.log(payment.email)      // ✅ 类型安全
      break
    case 'crypto':
      console.log(payment.wallet)     // ✅ 类型安全
      break
  }
}

这是一个第三方 Farrow 文档站 | 用 ❤️ 和 TypeScript 构建