Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.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
Javascript typescript能否推断参数已被验证?_Javascript_Typescript_Validation_Visual Studio Code - Fatal编程技术网

Javascript typescript能否推断参数已被验证?

Javascript typescript能否推断参数已被验证?,javascript,typescript,validation,visual-studio-code,Javascript,Typescript,Validation,Visual Studio Code,我还在学习Typescript和Javascript,如果我遗漏了什么,请原谅 问题如下: 当前,如果调用this.defined(email)时电子邮件未定义,VSCode不会推断我抛出错误。这是因为validateEmail()接受字符串?不会编译,因为它认为它仍然可以接收未定义的值(至少是我的推断)。有没有办法告诉编译器这没问题?还是我遗漏了什么 我想从其他类调用Validate.validateEmail(),问题也出现在这些类中 验证.ts 导出默认类验证{ 静态验证邮件(电子邮件?:

我还在学习Typescript和Javascript,如果我遗漏了什么,请原谅

问题如下:

当前,如果调用this.defined(email)时电子邮件未定义,VSCode不会推断我抛出错误。这是因为validateEmail()接受字符串?不会编译,因为它认为它仍然可以接收未定义的值(至少是我的推断)。有没有办法告诉编译器这没问题?还是我遗漏了什么

我想从其他类调用Validate.validateEmail(),问题也出现在这些类中

验证.ts
导出默认类验证{
静态验证邮件(电子邮件?:字符串){
//TODO:正确测试此正则表达式。
const emailRegex=new RegExp(“^([^()\[\]\\,;:\s@”+(\.[^()\[\]\,;:\s@”]+)*(“+”)(\[[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]+[1,3}.[1,3}]);([a-zA Z-0-9]+[a-Z]+]
本文件已定义(电子邮件);
这是一封电子邮件;
如果(!emailRegex.test(电子邮件)){
抛出新的SyntaxError(“输入的电子邮件无效”);
}
}
静态定义(文本?:字符串){
如果(!text){
抛出新的SyntaxError(“接收的文本未定义”);
}
}
静态notEmpty(文本:字符串){
如果(text.length<1){
抛出新的SyntaxError(“输入的文本为空”);
}
}
}

代码未编译的原因是notEmpty需要接受可为空的字符串。这是因为在调用站点,您正在传递一个可为null的字符串作为参数

export default class Validate {
    static validateEmail(email?: string) {
        // TODO: Test this regex properly.
        const emailRegex = new RegExp('^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$')

        this.defined(email);
        this.notEmpty(email);

        if (email && !emailRegex.test(email)) {
            throw new SyntaxError("The email entered is not valid");
        }
    }

    static defined(text?: string) {
        if (!text) {
            throw new SyntaxError("The text recieved was not defined.");
        }
    }

    static notEmpty(text?: string) {
        if (text && text.length < 1) {
            throw new SyntaxError("The text entered is empty.");
        }
    }
}
导出默认类验证{
静态验证邮件(电子邮件?:字符串){
//TODO:正确测试此正则表达式。
const emailRegex=new RegExp(“^([^()\[\]\\,;:\s@”+(\.[^()\[\]\,;:\s@”]+)*(“+”)(\[[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]+[1,3}.[1,3}]);([a-zA Z-0-9]+[a-Z]+]
本文件已定义(电子邮件);
这是一封电子邮件;
如果(电子邮件&!emailRegex.test(电子邮件)){
抛出新的SyntaxError(“输入的电子邮件无效”);
}
}
静态定义(文本?:字符串){
如果(!text){
抛出新的SyntaxError(“接收的文本未定义”);
}
}
静态notEmpty(文本?:字符串){
if(text&&text.length<1){
抛出新的SyntaxError(“输入的文本为空”);
}
}
}
您可以使用。类型保护声明特定变量的类型,如下所示:

export default class Validate {
  public static validateEmail(email?: string) {
    const emailRegex = new RegExp(
      '^(([^<>()[]\\.,;:s@"]+(.[^<>()[]\\.,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$'
    );

    if (!Validate.defined(email)) {
      throw new SyntaxError('The text recieved was not defined.');
    }

    if (!emailRegex.test(email)) {
      throw new SyntaxError('The email entered is not valid');
    }
  }

  public static defined(text?: string): text is string {
    return !!text;
  }

  public static notEmpty(text: string) {
    if (text.length < 1) {
      throw new SyntaxError('The text entered is empty.');
    }
  }
}

编译器有时可以通过以下方式在代码中的某些点识别变量的类型比其注释或推断的类型窄。在下面的代码块中,编译器理解,如果控制流到达
this.notEmpty()
调用,则
email
不能是
undefined
,因此没有错误:

if (!email) {
    throw new SyntaxError("The text received was not defined.");
}

this.notEmpty(email); // okay

但是,正如您所发现的,简单地重构代码以使检查在不同的函数中进行是行不通的。在执行控制流分析时,编译器通常不遵循控制流进入函数和方法。这是一个:编译器不可能通过分析通过所有可能函数调用的可能控制流路径来模拟在所有可能输入上运行的程序,因此它必须在某个地方使用启发式;在这种情况下,启发式通常是“假设函数调用对变量类型没有影响”。因此,调用
this.defined(email)
对编译器看到的
email
类型没有影响,因此它会抱怨
this.notEmpty(email)


幸运的是;您可以给一个函数一个特殊的返回类型,它告诉编译器传递给函数的变量将被函数缩小,并且它将使用它作为其控制流分析的一部分。虽然编译器本身不会推断此类函数签名,但至少现在您可以手动注释
defined()
断言其参数的某些内容:

static defined(text?: string): asserts text {
    if (!text) {
        throw new SyntaxError("The text recieved was not defined.");
    }
}
defined()。这修复了您最初的示例:

this.defined(email);
this.notEmpty(email); // okay now!
看起来不错。好吧,希望这会有帮助;祝你好运


ts中哪行抛出错误?此.notEmpty(电子邮件);他的目标是跳过检查
notEmpty
中的undefined,因为他之前已经调用了
defined
方法。这修复了编译,但没有解决问题。
认为它仍然可以接收未定义的值。
@ErikPhilips最好创建一个同时执行这两项检查的方法;未定义且非空的检查。我认为工具还不够聪明,无法检测到方法是按顺序调用的,notEmpty不能接收未定义的值。如果在代码中的另一个位置使用notEmpty(),而不调用defined(),该怎么办?请告诉我:)有时它是关于快速键入的。:)第二个答案似乎符合我在这一特定情况下的需要。我感谢你的帮助!
static defined(text?: string): asserts text {
    if (!text) {
        throw new SyntaxError("The text recieved was not defined.");
    }
}
this.defined(email);
this.notEmpty(email); // okay now!