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 commented line throws an Error at the argument: the Argument of type 'K' is not assignable to parameter of type 'K extends (infer T)[] ? T : K'.ts(2345), whereas the casted version works, and does not throw any errors.
As seen in this playground.
Why is typescript not able to infer, that on this line, K cannot be of type Array<any> and thus is allowed to be passed to the validation function?
Semantically:
If the second argument is of type K[], the function needs to accept K as a single parameter.
If the second argument is of type K[][], the function needs to accept multiple arguments of K.
E.g.
validate((x: number) => 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) => x%2, ['a', 'b']) should throw an error
validate((x: number) => x%2, [['a', 'a'], ['b', 'b']]) should throw an error
EDIT:
validate((x: number) => x % 2 === 0, [[1, 2, 3]]) should also throw an error, since validate would destructure the number[][] once, and try to call (x: number) => boolean with number[]
3.6.4. The examples are just to illustrate, what I want to achieve semantically. The problem is not the method-declaration (works fine in my code and the playground). The problem is in the body. I think I should not be required to cast thevalidationFunc. The issue becomes visible in playground (line 10) (see edit in question)