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

如何在io-ts中正确为解码函数标注类型?

解决方法

首先实现一个将DecoderError转换为标准Error的辅助函数:

import { DecoderError } from 'io-ts'

const toError = (err: DecoderError): Error => new Error(err.message)

接下来用mapLeft(而非fold)转换Either的左值类型——fold是用来将Either折叠为单一类型的,而我们需要保留Either结构,只替换左值类型:

import { mapLeft } from 'fp-ts/lib/Either'
import { pipe } from 'fp-ts/lib/function'

export const ObjC = Codec.struct({
  name: Codec.string,
  value: Codec.number,
})

export type ObjType = Codec.TypeOf<typeof ObjC>

const toError = (err: DecoderError): Error => new Error(err.message)

const decodeObj = async (str: string): Promise<Either<Error, ObjType>> => {
  return Promise.resolve(
    pipe(
      ObjC.decode(str),
      mapLeft(toError)
    )
  )
}

关键说明

  • mapLeft的作用:仅修改Either的左分支类型,右分支保持原类型,刚好匹配你需要的Either<Error, ObjType>结构。
  • 类型验证:函数的返回类型标注Promise<Either<Error, ObjType>>可以保留,TypeScript会自动验证内部转换是否符合该类型。如果解码逻辑不需要异步,也可以将函数改为同步,直接返回Either<Error, ObjType>。
  • 自定义错误信息:你可以根据DecoderError的具体结构(比如错误路径、详细描述)构造更丰富的Error,而不只是简单使用err.message。

如果解码过程需要真实异步操作(比如先从网络获取字符串),可以调整为:

const decodeObj = async (str: string): Promise<Either<Error, ObjType>> => {
  // 这里添加异步逻辑,比如await相关操作
  const decodeResult = ObjC.decode(str)
  return pipe(
    decodeResult,
    mapLeft(toError)
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 23:10:55