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

如何在io-ts中对输入数据使用类型细化并派生无品牌输入类型

解决方案

1. 你使用branded类型的选择是完全正确的

branded类型是io-ts中为基础类型附加额外校验规则的标准实现,刚好匹配你的需求:既可以在运行时执行正则校验,又能在类型层面区分「已经过校验的合法版本号」和「普通字符串」,避免未校验的值流入后续业务逻辑。

2. 无需重复定义类型,直接使用io-ts内置InputOf工具类型即可获得无品牌的输入类型

io-ts的所有Codec都自带输入/输出两类类型描述:

  • TypeOf<Codec> 是解码成功后的输出类型,也就是你现在用的带branded标记的安全类型
  • InputOf<Codec> 是Codec接受的输入类型,对于branded字符串来说,这个类型就是原生string,完全符合你的入参要求。

你只需要修改callFunction的入参类型即可,不需要新增任何自定义类型:

import { isRight } from 'fp-ts/Either';
import { brand, Branded, string, type, TypeOf, InputOf } from 'io-ts'; // 新增导入InputOf

interface VersionBrand {
  readonly Version: unique symbol;
}

export const TypeVersion = brand(
  string,
  (value: string): value is Branded<string, VersionBrand> =>
    /^\d+\.\d+\.\d+$/.test(value),
  'Version'
);

export const TypeMyStruct = type({
  version: TypeVersion,
});

export type Version = TypeOf<typeof TypeVersion>;
export type MyStruct = TypeOf<typeof TypeMyStruct>;

// 入参改用InputOf获取无品牌的输入类型
export function callFunction(data: InputOf<typeof TypeMyStruct>): boolean {
  const validation = TypeMyStruct.decode(data);
  // 校验通过后 validation.right 就是带branded标记的合法MyStruct类型,可直接用于后续安全逻辑
  return isRight(validation);
}

修改完成后,你就可以直接调用callFunction({ version: '1.2.3' }),编译不会报错,同时入参有完整的类型约束(只能传入version为字符串的对象,不会丢失类型信息变成any)。

如果你需要单独导出输入类型复用

可以直接基于InputOf定义,完全没有类型重复:

export type MyStructInput = InputOf<typeof TypeMyStruct>
// 等价于 type MyStructInput = { version: string }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 18:39:03