在单独的函数中进行类型检查在打字稿中不起作用

Type checking in separate function not working in typescript

我正在单独的函数中验证参数类型,但它仍然给出以下错误-

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');
  }
  
}

我想将验证逻辑放在一个单独的函数中以获得更清晰的代码。如何强制在验证后定义参数?

我认为将你的 try catch 块放在 if 块中会修复错误。因为参数验证器正在等待一个字符串,而你正在向它传递一个可能的未定义或字符串值。

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');
      }
    }
  
}

这是因为您使用了? 可选运算符,它告诉函数它可能在执行期间可用,这取决于您是否在 abc 函数中发送它。所以,它变成 undefined 直到没有使用该参数调用时间方法。

对于这种情况,您可以分配后备方法,即方法中的默认参数值。如果可以默认赋值,我不确定为什么需要验证器,最好使用空字符串而不是未定义的内容。

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');
  }
  
}

此外,当您有与之关联的对象和属性时,请尝试使用 ?? 检查它们的属性,将 null|undefined 属性设置为默认值,这样您就不会期望应用程序中出现任何不良行为。

正如 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');
  } 
}

如果参数实际上是一个字符串,您可以 return 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');
  }
}

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

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

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

任何时候调用此函数后,Typescript 都会识别出 param 的值应该是 string,并且不会出现错误。

Playground link