You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何序列化Typescript类型信息并从序列化结果恢复io-ts的Type对象

解决方案

1. 反序列化io-ts Type对象的实现思路

你提到的序列化后的io-ts Type结构自带_tag标识字段,完全可以通过递归匹配该字段还原对应的io-ts运行时类型,下面是可直接运行的最简实现:

import * as t from 'io-ts'

// 先定义序列化后的io-ts类型结构
interface SerializedIoTsType {
  _tag: string
  name: string
  props?: Record<string, SerializedIoTsType>
  type?: SerializedIoTsType // 数组元素类型
  types?: SerializedIoTsType[] // 联合类型成员
}

// 反序列化核心函数
function deserializeType(serialized: SerializedIoTsType): t.Any {
  switch (serialized._tag) {
    // 基础类型
    case 'NumberType': return t.number
    case 'StringType': return t.string
    case 'BooleanType': return t.boolean
    case 'NullType': return t.null
    case 'UndefinedType': return t.undefined
    // 复合类型
    case 'ArrayType': return t.array(deserializeType(serialized.type!))
    case 'InterfaceType': 
      const props = Object.fromEntries(
        Object.entries(serialized.props!)
          .map(([k, v]) => [k, deserializeType(v)])
      )
      return t.type(props, serialized.name)
    case 'UnionType': 
      const unionMembers = serialized.types!.map(deserializeType) as [t.Any, t.Any, ...t.Any[]]
      return t.union(unionMembers, serialized.name)
    // 用到其他io-ts类型(比如字面量、元组、交叉类型)直接在这里补case即可
    default: throw new Error(`不支持的io-ts类型:${serialized._tag}`)
  }
}

2. 整套跨进程类型校验的落地流程

因为原生TS类型编译后会被擦除,所以不可能直接从TS类型反向生成运行时类型,你可以基于io-ts和上面的反序列化函数实现你要的理想接口:

  1. 定义侧(事件生产方):统一用io-ts定义事件类型,既可以通过t.TypeOf推导得到原生TS类型,也可以直接序列化io-ts对象传给对端
  2. 注册阶段:生产方调用register接口时,序列化事件的io-ts对象传给消费方,消费方反序列化后存入本地事件类型映射表
  3. 发送阶段:生产方传事件时,TS层面会自动约束输入符合类型定义,消费方收到事件后用存储的io-ts类型做运行时校验,不符合直接返回错误

封装后的ContentGateway示例实现:

import * as t from 'io-ts'
import * as E from 'fp-ts/Either'

interface ContentGateway {
  // 注册:传入io-ts类型对象,内部自动序列化传输
  register: <T extends t.Any>(eventType: T) => E.Either<Error, void>;
  // 发送:传入io-ts类型对象和事件数据,TS编译阶段自动校验类型
  send: <T extends t.Any>(eventSchema: T, event: t.TypeOf<T>) => E.Either<Error, void>;
}

3. 注意事项

如果你的场景用到自定义branded类型、递归类型等复杂io-ts类型,只需要在反序列化函数中补充对应的_tag匹配逻辑即可,确保两端的自定义类型实现一致。


内容的提问来源于stack exchange,提问作者Adam A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 06:18:04