我目前正在为验证组件编写一些 typedef 和类,该组件正在构建以验证特定类(下面的“Main”)上的字段。目标:
MainValidationRule
) 应包含它正在验证的密钥 (T extends keyof Main
),以及验证相应值并返回指示有效性标志的验证函数 ({{1} }).(value: Main[T]) => boolean
) 映射到该字段的所有验证规则数组 ({{1} }).但是,当我尝试将规则映射到所需的结构化(下面的代码)时,TypeScript 给出了类型错误:
我会假设,因为 T in keyof Main
的任何给定值都保证 Array<MainValidationRule<T>>
将满足约束(即我们知道如果 rule.key
,那么 rule
将满足类型 rule.key === 'foo'
,同样适用于 'bar' 或任何其他可能添加到 rule
的键),这将编译正常。但是,TypeScript 似乎正在检查 MainValidationRule<'foo'>
的所有 可能的值是否是特定 键的有效规则,它失败了(例如){{1}如果键是 Main
,} 不是有效规则 - 尽管事实上我们的约束意味着这永远不可能。
我做错了吗?或者有没有另一种方法可以让 TypeScript 正确推断约束得到满足? MainValidationRule<keyof Main>
类经常使用新属性更新,因此手动输入并检查每个可能的变化是不切实际的。代码如下。提前致谢!
MainValidationRule<'bar'>
答案 0 :(得分:1)
有时最好使用联合类型而不是 Foo<keyof Bar>
为了清楚起见,只需比较我的 MainValidationRule
和 MainValidationRule<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
});