打字稿破译

时间:2018-06-28 06:03:24

标签: javascript typescript class transpiler

问题陈述:

定义类型为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());

在上面的代码中,我们将age变量定义为number,但是在创建类User的实例时,我将年龄"27"传递给了字符串。因此,在编译时,它应该引发错误,但会被毫无错误地编译为JavaScript。

翻译输出:

enter image description here

但是如果在相同的代码库中,我直接将字符串分配给构造函数中的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());

翻译输出:

enter image description here

1 个答案:

答案 0 :(得分:6)

这是预期的行为。您的构造函数具有3个没有类型注释的参数,因此其隐式类型将为any。您可以为any分配任何内容(因此可以为string分配any),也可以从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

通过将字段声明为构造函数参数,可以避免两次指定类型并进行赋值。以下代码与上述类等效:

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

如果要避免隐式包含类型为any的参数和变量,可以使用noImplicitAny编译器选项,如果未指定类型注释且无法推断类型,则会发生错误。