NodeJS 单独函数中的类型检查在typescript中无效

iszxjhcz  于 2023-05-17  发布在  Node.js
关注(0)|答案(7)|浏览(118)

我在单独的函数中验证参数的类型,但它仍然给出以下错误-
Argument of type 'string | undefined' is not assignable to parameter of type 'string'. Type 'undefined' is not assignable to type 'string'.
代码是这样的-

function paramValidator(param?: string){
  if(param===undefined){
    throw new Error('parameter missing');
  }
}
function xyz(a: string){
  console.log(a);
}

function abc(a?: string){
  try{
    paramValidator(a);
    // Working Fine
    // if(a===undefined){
    //   throw new Error('parameter missing');
    // }
    xyz(a);  //This line is throwing error
  }
  catch(e){
    console.log('Error');
  }
  
}

我想把验证逻辑放在一个单独的函数中,以使代码更简洁。如何强制在验证后定义参数?

mpgws1up

mpgws1up1#

如果您使用的是Typescript 3.7+,请使用Assert函数。变化很小;你只需在方法签名中添加一个asserts条件:

function paramValidator(param?: string): asserts params is string {

在你调用这个函数之后的任何时候,Typescript都会识别出param的值应该是string,你不会得到错误。
Playground链接

js81xvg6

js81xvg62#

如果参数实际上是一个字符串,则可以返回true,并将其用作条件

function paramValidator(param?: string): param is string {
  if(param===undefined){
    throw new Error('parameter missing');
  }
  return true;
}

function xyz(a: string){
  console.log(a);
}

function abc(a?: string){
  try{
    if (paramValidator(a)) {
        xyz(a);
    }
  }
  catch(e){
    console.log('Error');
  }
}
hfsqlsce

hfsqlsce3#

解决方案是使用xyz(a!),因为它将强制定义参数。我们已经在另一个函数中验证了该类型,所以在调用该函数时不需要这样做。

ifmq2ha2

ifmq2ha24#

这是因为你使用了?可选运算符,它告诉函数它在执行过程中可能是可用的,这取决于你是否在abc函数中发送它。因此,它变成undefined,直到没有使用该参数调用time方法。
对于这种情况,您可以在方法中分配一个回退,即默认参数值。我不知道为什么你需要有验证器,如果你可以默认赋值,它是好的,有空字符串,而不是一些未定义的。

function paramValidator(param?: string){
  if(param===undefined){
    throw new Error('parameter missing');
  }
}
function xyz(a: string){
  console.log(a);
}

function abc(a: string = ''){
  try{
    paramValidator(a);  // now you don't need to call it 
    // Working Fine
    // if(a===undefined){
    //   throw new Error('parameter missing');
    // }
    xyz(a);  //This line is throwing error
  }
  catch(e){
    console.log('Error');
  }
  
}

此外,当您有对象和属性与它相关联时,尝试使用??设置为空|将未定义的属性设置为默认值,因此您不会期望应用程序中出现任何不良行为。

oknrviil

oknrviil5#

我认为把你的try catch块放在if块里面会修复这个错误。因为param validator在等待一个字符串,而你正在向它传递一个可能的未定义或字符串值。

function abc(a?: string){
if(a){
    try{
        paramValidator(a);
        // Working Fine
        // if(req.a===undefined){
        //   throw new Error('parameter missing');
        // }
        xyz(a);  //This line is throwing error
      }
      catch(e){
        console.log('Error');
      }
    }
  
}
g2ieeal7

g2ieeal76#

正如Aprova Chikara所描述的,这是一个很好的解释和杰出的解决方案,为您的问题.但是如果你想坚持你的代码,并且还不想改变它的结构,你可以保持你的基本代码如下2个微小的变化:

function paramValidator(param?: string):string{
   if(param===undefined){
       throw new  Error("parameter missing");
   }
   return param;// 1
}

function xyz(a: string){
   console.log(a);
}

function abc(a?: string){
  try{
    a = paramValidator(a) // 2
    xyz(a);  //Now, this line is not throwing error!
  }
  catch(e){
    console.log('Error');
  } 
}
krugob8w

krugob8w7#

您可以在TS中使用Required关键字,例如Required<T>用于xyz函数。

type IParamValidatorParam = string | undefined;

function paramValidator(param: IParamValidatorParam){
  if(param === undefined){
    throw new Error('parameter missing');
  }
}
function xyz(a: Required<IParamValidatorParam>){
  console.log(a);
}

function abc(a: IParamValidatorParam){
  try{
    paramValidator(a);
    // Working Fine
    // if(a===undefined){
    //   throw new Error('parameter missing');
    // }
    xyz(a);  //This line is throwing error
  }
  catch(e){
    console.log('Error');
  }
}

但是,请确保在使用Required关键字之前仔细验证所有函数参数。

相关问题