有人能推荐一下如何缩小validateField功能内的类型吗?

type TStringValidator = (v: string) => void;
type TNumberValidator = (v: number) => void;

type TFields = 'inn' | 'amount';

interface IValidators {
  inn: TStringValidator[];
  amount: TNumberValidator[];
}

const handleString: TStringValidator = (value: string) => {};
const handleNumber: TNumberValidator = (value: number) => {};

const validators = {
  inn: [handleString],
  amount: [handleNumber],
} satisfies IValidators;

function validateField(field: TFields, value: string | number) {
  const fieldValidators = validators[field];

  for (const validator of fieldValidators) {
    // Problem is here
    const result = validator(value);
  }

  return;
}

链接到the TS playground.

预计validator(value)呼叫不会抛出TS错误:

Argument of type 'string | number' is not assignable to parameter of type 'never'.
  Type 'string' is not assignable to type 'never'.(2345)
(parameter) value: string | number

很明显,TS编译器无法根据field的值清楚地获取动态验证器的类型. 也许一些validateField重构可以有所帮助.

推荐答案

为了避免never类型,您可以在验证器中定义一组所有授权类型

type AllowedTypes = string & number;

然后在通用验证器函数的调用中,只需将变量强制转换为允许的类型

const result = validator(value as AllowedTypes);

全样本

type TStringValidator = (v: string) => void;
type TNumberValidator = (v: number) => void;

type TFields = 'inn' | 'amount';
type AllowedTypes = string & number;

interface IValidators {
  inn: TStringValidator[];
  amount: TNumberValidator[];
}

const handleString: TStringValidator = (value: string) => {};
const handleNumber: TNumberValidator = (value: number) => {};

const validators = {
  inn: [handleString],
  amount: [handleNumber],
}
satisfies IValidators;

function validateField(field: TFields, value: string | number) {
  const fieldValidators: (TNumberValidator | TStringValidator)[] = validators[field];

  for (const validator of fieldValidators) {
    const result = validator(value as AllowedTypes);
  }

  return;

Typescript相关问答推荐

用泛型类型覆盖父类函数导致类型y中的Property x不能赋给基类型Parent中的相同属性."'''''' "

对深度对象键/路径进行适当的智能感知和类型判断,作为函数参数,而不会触发递归类型限制器

根据上一个参数值查找参数类型,也返回类型

具有继承的基于类的react 组件:呈现不能分配给基类型中的相同属性

如何判断对象是否有重叠的叶子并产生有用的错误消息

为什么有条件渲染会导致material 自动完成中出现奇怪的动画?

我可以使用TypeScrip从字符串词典/记录中填充强类型的环境对象吗?

有没有可能产生输出T,它在视觉上省略了T中的一些键?

接口重载方法顺序重要吗?

如何在已知基类的任何子类上使用`extends`?

如何将v-for中的迭代器编写为v-if中的字符串?

->;Boolean类型的键不能分配给类型Never

界面中数组中的混合类型导致打字错误

重写返回任何

使用RXJS获取数据的3种不同REST API

Svelte+EsBuild+Deno-未捕获类型错误:无法读取未定义的属性(读取';$$';)

将带有额外id属性的Rust struct 展平回TypeScript单个对象,以返回wasm-bindgen函数

为什么 TypeScript 类型条件会影响其分支的结果?

解析错误:DeprecationError: 'originalKeywordKind' 自 v5.0.0 起已被弃用,无法再使用

为什么 typescript 在对象合并期间无法判断无效键?