类型定义中的感叹号
Posted
技术标签:
【中文标题】类型定义中的感叹号【英文标题】:Exclamation Mark in type definition 【发布时间】:2020-01-09 00:44:29 【问题描述】:目前我偶然发现了 Angular 的 ContentChildren decorator。在第一个代码示例中,使用了以下语法:
import AfterContentInit, ContentChildren, Directive, QueryList from '@angular/core';
@Directive(selector: 'child-directive')
class ChildDirective
@Directive(selector: 'someDir')
class SomeDir implements AfterContentInit
@ContentChildren(ChildDirective) contentChildren !: QueryList<ChildDirective>; // this line is relevant
ngAfterContentInit()
// contentChildren is set
注意@ContentChildren(ChildDirective) contentChildren
变量定义后面的感叹号和冒号。在this *** thread 中,我发现在访问变量或对象属性时,这种语法可以用作“非空断言运算符”。
我现在的问题是类型定义之前的感叹号是否与正常上下文中的含义完全相同。它只是简单地说 TypeScript 编译器:“好吧,不用担心 null
或未定义”,还是这种语法在这种情况下有其他特定含义?
【问题讨论】:
【参考方案1】:我现在的问题是,类型定义前的感叹号是否与正常上下文中的含义完全相同。
不,这实际上不是一回事,在这种情况下,它会做一些不同的事情。通常,当您声明一个成员(其类型中不包含undefined
)时,必须直接或在构造函数中对其进行初始化。如果你在名字后面加上!
,TypeScript 会忽略它,如果你不立即初始化它就不会报错:
class Foo
foo: string; // error: Property 'foo' has no initializer and is not definitely assigned in the constructor.
bar!: string; // no error
同样的事情实际上也适用于局部变量:
let foo: string;
let bar!: string;
console.log(foo); // error: Variable 'foo' is used before being assigned.
console.log(bar); // no error
Playground
【讨论】:
此功能是在 TS2.7 中添加的。相关文档:definite assignment assertions with!
以上是关于类型定义中的感叹号的主要内容,如果未能解决你的问题,请参考以下文章