使用KeyOf作为属性时,类型脚本无法从泛型中正确推断类型 [英] TypeScript failing to correctly infer types from generic using keyof as property

查看:0
本文介绍了使用KeyOf作为属性时,类型脚本无法从泛型中正确推断类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在为一个验证组件编写一些typedef和类,该组件被构造为验证特定类(下面的‘main’)上的字段。目标:

  1. 每个验证规则(MainValidationRule)应包含它正在验证的键(T extends keyof Main),以及验证相应值并返回指示有效性的标志的验证函数((value: Main[T]) => boolean)。
  2. 为便于使用验证器,在运行时将验证规则数组组装成一个对象,将每个字段(T in keyof Main)映射到该字段(Array<MainValidationRule<T>>)的所有验证规则数组。

但是,当我尝试将规则映射到所需的结构化(如下代码)时,TypeScrip显示类型错误:

Image of type error

我会假设,因为rule.key的任何给定值都保证rule将满足约束(即。我们知道,如果rule.key === 'foo',那么rule将满足类型MainValidationRule<'foo'>,‘bar’或可能添加到Main的任何其他键也是如此),这将很好地编译。但相反,TypeScrip似乎正在检查MainValidationRule<keyof Main>的所有可能值是否都是特定键的有效规则,如果键是'foo',则MainValidationRule<'bar'>不是有效规则,尽管我们的限制意味着这永远不可能。

我做错了什么吗?或者,有没有其他方法可以让TypeScrip正确地推断出约束条件得到满足?Main类使用新属性频繁更新,因此手动输入并检查每个可能的变化是不切实际的。代码如下。提前感谢!

type Main = {
    foo: string;
    bar: number;
};

type MainValidationRule<T extends keyof Main> = {
    key: T;
    isValid: (value: Main[T]) => boolean;
};

type MainValidationRulesMap = { [ T in keyof Main ]?: Array<MainValidationRule<T>> };
const mainValidationRulesMap: MainValidationRulesMap = {};
const mainValidationRules: Array<MainValidationRule<keyof Main>> = [];

mainValidationRules.forEach(rule => {
    mainValidationRulesMap[rule.key] = [ rule ]; // type error
});

推荐答案

有时最好使用联合类型而不是Foo<keyof Bar>

为了清楚起见,只需比较MyMainValidationRuleMainValidationRule<keyof Main>

看起来它们是相等的,但事实并非如此。

对于TS,推断简单的联合类型要容易得多。

代码如下:

type Main = {
  foo: string;
  bar: number;
};

type Values<T> = T[keyof T]

type MainValidationRule = Values<{
  [P in keyof Main]: {
    key: P;
    isValid: (value: Main[P]) => boolean;
  }
}>

type Rules = Array<MainValidationRule>


type MainValidationRulesMap = Partial<{ [T in keyof Main]: Rules }>;

const mainValidationRulesMap: MainValidationRulesMap = {};

const mainValidationRules: Rules = [];

mainValidationRules.forEach(rule => {
  mainValidationRulesMap[rule.key] = [rule]; // ok
});

Playground

这篇关于使用KeyOf作为属性时,类型脚本无法从泛型中正确推断类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆