是否可以编写类型AllValidators
,以确保其类型的对象具有ALL
中的ValidatorName
键,并且每个属性都保持其原始类型?
因此底部的const validator
的类型为Validator<string>
。
(我不想 validator
为any
,Validator<any>
,Validator<string|number|boolean>
)
谢谢!
type ValidatorName = 'maxLength' | 'required' | 'regexp';
type Validator<P> = {
(value: string, param: P): boolean;
};
type AllValidators = {
[key in ValidatorName]: ???
}
const allValidators: AllValidators = {
maxLength: ((value: string, param: number) => false) as Validator<number>,
required: ((value: string, param: boolean) => false) as Validator<boolean>,
regexp: ((value: string, param: string) => false) as Validator<string>,
}
const validator = allValidators.regexp
答案 0 :(得分:1)
不能有一个既受接口限制又不能根据分配的值推断其类型的变量。您可以改为使用带有类型参数的函数。类型参数可以有一个约束,但是实际的参数类型将从调用中捕获。
type ValidatorName = 'maxLength' | 'required' | 'regexp';
type Validator<P> = {
(value: string, param: P): boolean;
};
function createAllValidators<T extends { [P in ValidatorName]: Validator<any> }>(o: T) {
return o;
}
const allValidators = createAllValidators({
maxLength: ((value: string, param: number) => false),
required: ((value: string, param: boolean) => false),
regexp: ((value: string, param: string) => false),
})
const validator = allValidators.regexp
// { maxLength: number; required: boolean; regexp: string; }
type Rules = {
[P in keyof typeof allValidators] : (typeof allValidators[P] extends Validator<infer T>? T: never)
}
答案 1 :(得分:0)
好吧,如果您颠倒逻辑并在位置中键入并使用typeof
来简单地捕获allValidators
的类型,则非常简单:
type Validator<P> = {
(value: string, param: P): boolean;
};
const allValidators = {
maxLength: ((value: string, param: number) => false) as Validator<number>,
required: ((value: string, param: boolean) => false) as Validator<boolean>,
regexp: ((value: string, param: string) => false) as Validator<string>,
}
type AllValidators = typeof allValidators;
const validator = allValidators.regexp
您甚至不再需要ValidatorName
(而且是否也需要AllValidators
也是有争议的。)