Skip to content

DTO 与类型规则

DTO(数据传输对象)是 fun 的参数契约。框架在注册期检查类型合法性(违反直接 panic),在运行期校验必传字段与枚举值域。规则的设计目标是:类型即文档、错配在最早的时机暴露。

允许与禁止

✅ 允许❌ 禁止(注册期 panic)
定宽整型:int8/16/32/64uint8/16/32/64普通 int / uint
stringfloat32 / float64(小数用字符串传)
boolmapany / interface{}
具名 struct(嵌套 DTO)匿名结构体
slice([]T,T 合法即可)空结构体、私有字段
指针 *T(T 合法即可)

为什么禁止普通 int 和 float:

  • int 平台相关宽度,跨端(Go ↔ JS)无法稳定契约,TS 侧需要明确的位宽;
  • JSON 数字在 JS 里是 double,小数传丢失精度路径太多,小数一律用字符串(如 "199.00"),由业务两端自行解析。

必传与可空

go
type SaveSettingsDto struct {
    SiteName string   // 非指针、非 slice → 必传且非 null
    Rate     *string  // 指针 → 可省略(nil)
    Count    *int64   // 可空数值用指针
    Tags     []string // slice → 可省略(nil)
}
  • 非指针且非 slice 的字段必传:请求里漏传或显式传 null,运行期返回 must be a pointer or have a corresponding field
  • 可空字段一律用 *T:省略时保持 nil,业务里 if dto.Note != nil 判断;
  • 请求字段名大小写不敏感siteName / SiteName / SITENAME 均可匹配(转换是 JSON marshal/unmarshal 往返)。

大整数与 BigInt

雪花 ID 等超过 2^53 - 1 的整数全链路 int64 精度:

  • 服务端:DTO 解码直接走原始字节,不经 float64 往返,无精度丢失;
  • TS 客户端:生成的 client.ts 内置无损 JSON 解析,超出 Number.MAX_SAFE_INTEGER 的整数字面量自动解析为 BigInt,序列化时还原为数字字面量。
ts
const r = await c.orderSvc.create({ sku: 'A', count: 1 })
r.data!.id   // 9007199254740993 → BigInt,不是被舍入的 Number

枚举

uint8 底层 + 实现 Names() []string 即成为枚举:

go
type OrderStatus uint8

func (OrderStatus) Names() []string { return []string{"Pending", "Paid", "Shipped"} }

// 可选:展示名(给前端下拉框用),长度必须与 Names 一致
func (OrderStatus) DisplayNames() []string { return []string{"待支付", "已支付", "已发货"} }
  • 值域:0 ~ len(Names())-1,运行期传越界值(如 3)报错;
  • TS 侧生成对应的 enum/类型定义,DisplayNames 一并下发。

指针枚举 *OrderStatus = 可空枚举,缺省时业务自行给默认值(如 Pending)。

响应侧规则

  • 返回值 T 同样受类型检查(具名 struct / 定宽整型 / string / bool / slice / 指针);
  • 所有响应键递归转首字母小写SiteNamesiteName),前端直接按 camelCase 取值,无需任何配置;
  • 成功时空 slice 序列化为 [] 而非 nulldata 为 nil 时整个字段省略。

注册期 panic 速查

panic 信息原因
Unsupported types intDTO 字段用了 int/uint/float/map/any/匿名结构体/私有字段
method X has more than one parameter方法参数超过 1 个
method X parameter must be a struct参数不是 struct(如传了 int64
method X must return (error), (T, error)...返回值不符合四种签名

下一步

基于 MIT 许可发布