Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用typescript泛型推断param函数的类型 functionvalidate(validationFunc:(…args:(K扩展数组?T:K)[])=>boolean,validationArgs:K[]):boolean{ 让res:布尔; for(const validationArg of validationArgs){ if(Array.isArray(validationArrag)){ res=validationFunc(…validationArg); }否则{ //res=validationFunc(validationArg); res=(validationFunc as(args:K)=>boolean)(validationArg); } 如果(!res) 返回false; } 返回真值 }_Typescript_Type Inference_Typescript Generics - Fatal编程技术网

使用typescript泛型推断param函数的类型 functionvalidate(validationFunc:(…args:(K扩展数组?T:K)[])=>boolean,validationArgs:K[]):boolean{ 让res:布尔; for(const validationArg of validationArgs){ if(Array.isArray(validationArrag)){ res=validationFunc(…validationArg); }否则{ //res=validationFunc(validationArg); res=(validationFunc as(args:K)=>boolean)(validationArg); } 如果(!res) 返回false; } 返回真值 }

使用typescript泛型推断param函数的类型 functionvalidate(validationFunc:(…args:(K扩展数组?T:K)[])=>boolean,validationArgs:K[]):boolean{ 让res:布尔; for(const validationArg of validationArgs){ if(Array.isArray(validationArrag)){ res=validationFunc(…validationArg); }否则{ //res=validationFunc(validationArg); res=(validationFunc as(args:K)=>boolean)(validationArg); } 如果(!res) 返回false; } 返回真值 },typescript,type-inference,typescript-generics,Typescript,Type Inference,Typescript Generics,注释行在参数处抛出错误:类型为“K”的参数不可分配给类型为“K extends(推断T)[]的参数?T:K'.ts(2345),而强制转换的版本可以工作,并且不会抛出任何错误。 如图所示 为什么typescript无法推断,在这一行上,K不能是Array类型,因此允许传递给验证函数 语义上: 如果第二个参数的类型为K[],则函数需要接受K作为单个参数。 如果第二个参数的类型为K[][,则函数需要接受多个K参数 例如 validate((x:number)=>x%2[1,2,3])应该可以 val

注释行在参数处抛出错误:
类型为“K”的参数不可分配给类型为“K extends(推断T)[]的参数?T:K'.ts(2345)
,而强制转换的版本可以工作,并且不会抛出任何错误。 如图所示

为什么typescript无法推断,在这一行上,
K
不能是
Array
类型,因此允许传递给验证函数

语义上: 如果第二个参数的类型为
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]])
也应该抛出一个错误,因为validate会将
number[][]
分解一次,然后尝试调用
(x:number)=>布尔值
number[]
我认为您不需要推断param函数的类型。正如您所解释的,您的验证参数可以是
K[]|K[][

当您调用validate函数
x%2
时,我也做了一个小改动,它应该包装在
Boolean()
中,否则返回值将不正确

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
}
函数验证布尔值,P扩展参数>(validationFunc:T,validationArgs:P[]):布尔值{
让res:布尔;
for(const validationArg of validationArgs){
res=validationFunc(validationArg);
如果(!res)
返回false;
}
返回真值
}
函数简化布尔值,P扩展参数>(validationFunc:T,validationArgs:P[]):布尔值{
返回validationArgs.every((args)=>validationFunc(args));
}
验证((x:number)=>Boolean(x%2),[[1],[2],[3]])//应该可以
验证((a:string,b:string)=>a==b,[[['a',a'],['b',b']])//应该是正常的
validate((x:number)=>Boolean(x%2),[['a'],['b']])//应引发错误
validate((x:number)=>Boolean(x%2),[['a','a'],['b','b']])//应引发错误
验证((x:number)=>x%2==0,[[1,2,3]]);//应该抛出一个错误

我和我得到了你想要的。您使用TS的哪个版本/编译器选项?我使用最新版本
3.6.4
。这些例子只是为了说明,我想在语义上实现什么。问题不在于方法声明(在我的代码和游戏中效果很好)。问题出在身体上。我想我不应该被要求强制转换
validationFunc
。这个问题在操场(第10行)中变得可见(请参见有问题的编辑)好的,我添加了另一个示例,如果我不推断内部类型,则不会发现错误。对不起,我刚才错过了。如果不是这样,您的解决方案工作正常,但可能会在运行时导致错误。(与我的一样)编辑,但需要做一些改变,我不认为你试图实现的是可能的,如果有人找到一个更好的答案,我很好奇自己:)我认为,当您将
[1,2,3]
作为参数提供时,这是不明确的,因为它可以用于一个具有3个参数的函数的执行或一个具有1个参数的函数的3个执行。此外,还添加了一个简化版本,您可能只需要使用
数组就可以做到这一点。在我看来,every()
@Grabofus。我总是提供一个数组。此数组中的每个项将用于一次迭代。如果此外部数组中的项本身是数组,则应将它们分散并作为单个参数传递给validationFunc<代码>[1,2,3]
->三次迭代,每次迭代一个编号
validationFunc(x)
[[1,2,3]]
=>只调用一次
vaildationFunc(1,2,3)
@RobertKoritnik
每个
都与否定的
部分
相同,它将在第一次
false时停止
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