【发布时间】:2021-05-01 00:43:33
【问题描述】:
我目前正在为验证组件编写一些 typedef 和类,该组件正在构建以验证特定类(下面的“Main”)上的字段。目标:
- 每个验证规则 (
MainValidationRule) 都应包含它正在验证的键 (T extends keyof Main),以及一个验证相应值并返回指示有效性的标志 ((value: Main[T]) => boolean) 的验证函数。 - 为了便于使用验证器,在运行时,验证规则数组将组合成一个对象,将每个字段 (
T in keyof Main) 映射到该字段的所有验证规则数组 (Array<MainValidationRule<T>>)。
但是,当我尝试将规则映射到所需的结构(下面的代码)时,TypeScript 会出现类型错误:
我会假设,因为rule.key 的任何给定值都保证rule 将满足约束条件(即,我们知道如果rule.key === 'foo',那么rule 将满足MainValidationRule<'foo'> 类型,并且'bar' 或任何其他可能添加到Main 的键也是如此,这样可以很好地编译。但相反,TypeScript 似乎正在检查 MainValidationRule<keyof Main> 的 所有 可能值是否是 特定 键的有效规则,它失败了(例如)MainValidationRule<'bar'> 不是如果键是 'foo' 则为有效规则 - 尽管事实上我们的约束意味着这永远不可能。
我做错了吗?还是有另一种方法可以让 TypeScript 正确推断出满足约束? 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
});
【问题讨论】:
标签: typescript typescript-generics