【发布时间】:2019-12-06 09:20:47
【问题描述】:
无论好坏,我都有一个以 3 元组形式传输数据的 API:(EntityName, FieldName, Value)。还提供了id,但为了这次谈话,它可能没有实际意义。
EntityName 表示记录类型,FieldName 应该是该特定记录的键。 Value 应该是适合 FieldName 类型的值。
如果我知道EntityName 和FieldName 已经有效,我正试图弄清楚如何编写一个函数,给定这个元组,可以验证Value。
我已尝试以多种方式编写此代码,我相信我在下面展示的那一种是最优雅的。但是,如果不进行类型断言,我无法找到任何可行的方法,我很好奇为什么类型检查器无法确定这将起作用,考虑到 Validator 的定义方式和 @987654331 的方式@ 已定义,我希望没有投诉。
话虽如此,我还不知道我是否达到了类型检查的理论限制,或者这可能是一个错误?
export enum EntityName {
A = 'A',
B = 'B',
};
interface IEntityA {
fieldA: boolean;
}
interface IEntityB {
fieldB: string;
}
type Entity<Name extends EntityName> =
Name extends EntityName.A ? IEntityA :
Name extends EntityName.B ? IEntityB :
never;
const Validator: {
[Name in EntityName]: {
[FieldName in keyof Entity<Name>]: (value: unknown) => value is Entity<Name>[FieldName];
};
} = {
[EntityName.A]: {
fieldA: (value: unknown): value is boolean => typeof value === 'boolean',
},
[EntityName.B]: {
fieldB: (value: unknown): value is string => typeof value === 'string',
},
};
const isValueValid = <
Name extends EntityName,
FieldName extends keyof Entity<Name>,
>(
entityName: Name,
fieldName: FieldName,
value: unknown,
): value is Entity<Name>[FieldName] => {
return Validator[entityName][fieldName](value);
};
编译器在isValueValid 内部给了我这个错误:
Type 'FieldName' cannot be used to index type '{ A: { fieldA: (value: unknown) => value is boolean; }; B: { fieldB: (value: unknown) => value is string; }; }[Name]'.
有趣的是,传递给isValueValid 的参数类型检查正确。
【问题讨论】: