打字稿打破

Roh*_*dal 1 javascript class transpiler typescript

问题陈述 :

使用类型定义变量,number但是在将任何字符串分配到此变量中并尝试将transpile其转换为JavaScript时.Transpiler没有任何错误.

问题演示:

class.ts

class User {
    age:number;
    name:string;
    phone:number | string;

    constructor(a, n, p) {
        this.age = a;
        this.name = n;
        this.phone = p;
    }

    getDetails() {
        return "Age : " + this.age + ", Name : " + this.name + ", Phone : " + this.phone;
    }
}

var firstUser = new User("27", "Rohit", "945*****44");

console.log(firstUser.getDetails());
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我们将age变量定义为number但是在创建类的实例时,User我传递的是age,"27"即string.因此,虽然转换它应该抛出错误但它被转换成JavaScript而没有任何错误.

经过输出:

在此输入图像描述

但是在相同的代码库中,如果我直接将字符串this.age赋值给构造函数中的变量.Transpiler会抛出错误.

class.ts

class User {
    age:number;
    name:string;
    phone:number | string;

    constructor(a, n, p) {
        this.age = "27";
        this.name = n;
        this.phone = p;
    }

    getDetails() {
        return "Age : " + this.age + ", Name : " + this.name + ", Phone : " + this.phone;
    }
}

var firstUser = new User("27", "Rohit", "945*****44");

console.log(firstUser.getDetails());
Run Code Online (Sandbox Code Playgroud)

经过输出:

在此输入图像描述

Tit*_*mir 6

这是预期的行为.您的构造函数有3个参数,没有类型注释,因此它们的隐式类型将是any.您可以将任何东西any(所以你可以分配stringany),你可以从分配any(这样你就可以分配number从外地a类型的参数any).在这种情况下,基本上any会删除传入的任何类型.

既然a应该是一个数字,我们应该提供一个明确的注释,然后当我们传入一个string(这是预期的行为)时我们会得到一个错误

class User {
    age:number;
    name:string;
    phone:number | string;

    constructor(a: number, n: string, p: number | string) {
        this.age = a;
        this.name = n;
        this.phone = p;
    }

    getDetails() {
        return "Age : " + this.age + ", Name : " + this.name + ", Phone : " + this.phone;
    }
}

var firstUser = new User("27", "Rohit", "945*****44"); // error
var secondUser = new User(27, "Rohit", "945*****44"); // ok
Run Code Online (Sandbox Code Playgroud)

您可以避免必须两次指定类型并通过将字段声明为构造函数参数来执行赋值.以下代码相当于上面的类:

class User {

    constructor(
        public age:number, // Both a constructor argument and a field declaration, the compiler will perform the this.age = age assignemet for us
        public name:string,
        public phone:number | string) {
    }

    getDetails() {
        return "Age : " + this.age + ", Name : " + this.name + ", Phone : " + this.phone;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果要避免隐式具有类型的参数和变量,则any可以使用noImplicitAny编译器选项在未指定类型注释且无法推断类型时出现错误.