class Employee {
firstName: string;
lastName!: string;
middleName?: string;
}
firstName: string表示firstName必须是string。null或undefined不是名字的有效值。 所有未初始化的字段都将具有默认值undefined,因此这将导致错误Property 'firstName' has no initializer and is not definitely assigned in constructor 要消 debugging 误,您需要将声明更改为firstName: string = 'Some default value',或者添加一个构造函数并在构造函数中为它赋值。
class Employee {
firstName: string;
lastName!: string;
middleName?: string;
constructor() {
// This will silence the compiler about first name not initialized
this.firstName = 'some default value';
// The compiler cannot tell that lastName is assigned in init() function
this.init();
}
private init(): void {
this.lastName = 'some default value';
}
}
4条答案
按热度按时间dw1jzc5e1#
具有编译器选项
strictNullChecks: false
时如果您的
tsconfig.json
中有strictNullChecks: false
,则它们完全相同,因为禁用strictNullChecks
意味着所有字段都可以将null或undefined作为有效值。具有编译器选项
strictNullChecks: true
时firstName: string
表示firstName
必须是string
。null
或undefined
不是名字的有效值。所有未初始化的字段都将具有默认值
undefined
,因此这将导致错误Property 'firstName' has no initializer and is not definitely assigned in constructor
要消 debugging 误,您需要将声明更改为
firstName: string = 'Some default value'
,或者添加一个构造函数并在构造函数中为它赋值。现在来看看!语法。
lastName!: string
语法与lastName: string
类似,基本上是说string
是唯一允许的类型。null
和undefined
是不允许的。但是它会让编译器对明确的赋值错误保持沉默。假设您有以下代码。在前面的代码中,
lastName
通过this.init()
调用在constructor
中被明确赋值,但是编译器不知道这一点,所以添加!基本上就是告诉编译器 “闭嘴,我知道我在做什么”,然后由您来确保代码的正确性。关于
middleName?: string
语法。这与middleName: string | undefined
类似;因为所有的值都有一个默认值undefined
,所以编译器不会抱怨middleName
没有赋值。1l5u6lss2#
该位置的
?
将属性标记为可选。这个位置的
!
是明确赋值Assert,它是非空Assert操作符的声明级版本,但用于属性(也可以用于变量)而不是表达式。在这个例子中有两个--或者可以说是三个--错误:
Class
应为class
;JavaScript和TypeScript区分大小写。1.在
firstName
上需要一个初始化器(或者一个无条件赋值给它的构造函数)。lastName
上的!
告诉TypeScript,lastName
肯定会被赋值,从而抑制了您在firstName
上遇到的那种错误,但(在示例中)没有任何东西实际上 * 执行 * 赋值,即使用!
可以保证TypeScript您确信您正在执行赋值。lastName
从未被赋值,并假设它的值是一个字符串,而事实上它并不存在,因此阅读它的值将导致undefined
。*8tntrjer3#
它们很好地隐藏在documentation of TypeScript中。
?
在interfaces上描述,它标记了一个可选属性。!
是明确Assert运算符。它告诉编译器属性已设置(不是null
或undefined
),即使TypeScript的分析无法检测到。顺便说一句,
Class
不是TypeScript或JavaScript关键字,在那个位置会产生错误。声明类的关键字是class
。TypeScript和JavaScript标识符和关键字区分大小写(Class
和class
是不同的东西)。5q4ezhmt4#
在TypeScript中,**!和?**字符用于指示对象类型定义中的可选属性和不可为空的属性。
**!**字符用于指示不可为空的属性,这意味着该属性是必需的并且必须具有值。例如:
**?**字符用于指示可选属性,表示该属性不是必需的,可以不定义。例如:
在本例中,age属性是可选的,不需要定义。
需要注意的是,当您在接口中使用**!时,它意味着变量是必需的,您不能将
null
或undefined
赋给它,但如果您使用?**,则变量不是必需的,但您仍然可以将null
或undefined
赋给它。