我正在尝试编写一个泛型类型,该类型将基于另一个属性(field
(的值强制执行给定属性(value
(的类型,其中field
的值是作为泛型参数提供的类型中的键。
以下是我尝试过的:
type Rule<M, F extends keyof M = keyof M> = {
field: F;
value: M[F];
};
用法:
interface MyModel {
firstName: string;
lastName: string;
age: number;
isActive: boolean;
}
const rule1: Rule<MyModel> = {
field: 'age',
value: 'twentynine'
// ^^ string | number | boolean
};
目前,无论rule1.field
的值是多少,rule1.value
的类型都是MyModel
中所有类型的并集
相反,我希望rule1.value
是number
类型,因为值";年龄;我提供给rule1.field
的是MyModel
中的密钥,类型是number
。
以下示例没有错误:
const rule2: Rule<MyModel> = {
field: 'age',
value: 29
};
const rule3: Rule<MyModel> = {
field: 'firstName',
value: 'George'
};
您的方法不起作用,因为无法从对象赋值中推断出F
类型。
这里有一个可能的解决方案来解决您的问题,它包括使用映射类型,以便与接口的每个条目建立一个联合类型:
type Rule<T> = {
[K in keyof T]: { field: K, value: T[K] };
}[keyof T];
interface MyModel {
firstName: string;
lastName: string;
age: number;
isActive: boolean;
};
const rule1: Rule<MyModel> = {
field: 'age',
value: 'twentynine'
};
const rule2: Rule<MyModel> = {
field: 'age',
value: 29
};
TypeScript游乐场