function validate<K>(validationFunc: (...args: (K extends Array<infer T> ? T : K)[]) => boolean, validationArgs: K[]): boolean {
let res: boolean;
for (const validationArg of validationArgs) {
if (Array.isArray(validationArg)) {
res = validationFunc(...validationArg);
} else {
// res = validationFunc(validationArg);
res = (validationFunc as (args: K) => boolean)(validationArg);
}
if(!res)
return false;
}
return true
}
带注释的行在参数the Argument of type 'K' is not assignable to parameter of type 'K extends (infer T)[] ? T : K'.ts(2345)
上引发错误,而强制转换的版本起作用,并且不引发任何错误。
如this playground所示。
为什么打字稿不能推断,在这一行上,K
不能是Array<any>
类型,因此可以传递给验证函数?
语义上:
如果第二个参数的类型为K[]
,则该函数需要接受K
作为单个参数。
如果第二个参数的类型为K[][]
,则该函数需要接受多个K
的参数。
例如
validate((x: number) => x%2, [1, 2, 3])
应该没问题
validate((a: string, b: string) => a === b, [['a', 'a'], ['b', 'b']])
应该没问题
validate((x: number) => x%2, ['a', 'b'])
应该抛出错误
validate((x: number) => x%2, [['a', 'a'], ['b', 'b']])
应该抛出错误
编辑:
validate((x: number) => x % 2 === 0, [[1, 2, 3]])
也应该引发错误,因为验证会破坏number[][]
一次,并尝试用(x: number) => boolean
调用number[]
答案 0 :(得分:1)
我认为您不需要推断param函数的类型。正如您所解释的,您的验证参数可以仅为K[] | K[][]
。
当您调用验证函数x % 2
应该包裹在Boolean()
中时,我也做了一些小的更改,否则返回值将不正确。
function validate<T extends (...args: any) => boolean, P extends Parameters<T>>(validationFunc: T, validationArgs: P[]): boolean {
let res: boolean;
for (const validationArg of validationArgs) {
res = validationFunc(validationArg);
if(!res)
return false;
}
return true
}
function simplified<T extends (...args: any) => boolean, P extends Parameters<T>>(validationFunc: T, validationArgs: P[]): boolean {
return validationArgs.every((args) => validationFunc(args));
}
validate((x: number) => Boolean(x % 2), [[1], [2], [3]]) // should be ok
validate((a: string, b: string) => a === b, [['a', 'a'], ['b', 'b']]) // should be ok
validate((x: number) => Boolean(x % 2), [['a'], ['b']]) // should throw an error
validate((x: number) => Boolean(x % 2), [['a', 'a'], ['b', 'b']]) // should throw an error
validate((x: number) => x % 2 === 0, [[1, 2, 3]]); // should throw an error