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 显式为 nullOptional 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:
| 特性 | ObjectType | Struct |
|---|---|---|
| 定义方式 | 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
}
}