跳到主要内容

稳定兼容:JSON To io-ts类型 — Numio

根据 JSON 示例生成 io-ts 运行时 codec,开头为 import * as t from "io-ts"。嵌套对象各自成为 codec,并声明在使用它们的 codec 之前;数组中部分元素缺少的键放入 t.partial。

在基于 fp-ts 和 io-ts 的 TypeScript 应用中于运行时校验 API 响应。

JSON

IO TS

适用场景

  • 在基于 fp-ts 和 io-ts 的 TypeScript 应用中于运行时校验 API 响应。
  • 为使用前必须校验的 JSON 配置文件起草 codec。

使用方法

  1. 粘贴 JSON 对象;如果有可选键,请包含多个数组元素。
  2. 查看生成的 codec:根为 RootInterface,嵌套 codec 按键名命名(settings 变为 Settings)。
  3. 复制代码,导出需要的 codec,并用 t.TypeOf 派生类型。

JSON 输入

{
  "id": "u_1",
  "name": "Ada",
  "age": 36,
  "nickname": null,
  "settings": { "theme": "dark", "fontSize": 14 },
  "posts": [
    { "title": "Notes", "draft": true },
    { "title": "Engine" }
  ]
}

io-ts codec

import * as t from "io-ts"

const Settings = t.type({
  theme: t.string,
  fontSize: t.number,
})

const Posts = t.intersection([
  t.type({
    title: t.string,
  }),
  t.partial({
    draft: t.boolean,
  }),
])

const RootInterface = t.type({
  id: t.string,
  name: t.string,
  age: t.number,
  nickname: t.null,
  settings: Settings,
  posts: t.array(Posts),
})

功能与限制

在浏览器中由本站自己的生成器生成并用 Prettier 格式化;页面没有设置项,也不发起服务器请求。

codec 按依赖优先的顺序输出,因此每个 const 都在 RootInterface 引用之前定义。

数字一律变为 t.number(整数和小数相同)。null 得到 t.null,若其他示例有值则为 t.union([X, t.null]);空数组得到 t.array(t.unknown)。

数组中部分元素缺少的键放入 t.partial,并通过 t.intersection 与必需键组合。

FAQ

也会生成 TypeScript 类型吗?

不会直接生成。添加 type Root = t.TypeOf<typeof RootInterface>,即可从每个 codec 派生静态类型。

可选或可空字段如何处理?

数组中部分元素缺少的键放入 t.partial;在部分元素中为 null 的键变为 t.union([type, t.null])。单个对象的顶层键始终是必需的。

根节点为 JSON 数组时会怎样?

元素会合并为一个描述元素结构的 RootInterface codec,并添加表示整个数组的 const RootInterfaceList = t.array(RootInterface)。

规范与参考资料