如何在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
相关产品推荐
相关产品推荐

