问题陈述:
定义类型为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。
翻译输出:
但是如果在相同的代码库中,我直接将字符串分配给构造函数中的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());
翻译输出:
答案 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
编译器选项,如果未指定类型注释且无法推断类型,则会发生错误。