打字稿:不带参数的函数调用

时间:2019-09-09 06:51:11

标签: angular typescript function

我对TypeScript还是很陌生,最近发现了以下形式的表达形式:

class AsyncPromisePipeComponent{

  private resolve: Function|null = null;
  (...)
  this.resolve !('hi there!');
}

由于this.resolve !('hi there!')是一个函数,因此我很难理解this.resolve。这是不带括号的函数调用吗? !代表什么(因为您不能否定字符串,可以)吗?

我在官方Angular Doc for the AsyncPipe中找到了这个。也许只是一个错字。否则:有人可以解释this.resolve !('hi there!');的含义吗?

2 个答案:

答案 0 :(得分:2)

剧院是non-null assertion operator。它告诉编译器在它之前的表达式既不是undefined也不是null

这是上下文的整个示例:

export class AsyncPromisePipeComponent {
  greeting: Promise<string>|null = null;
  arrived: boolean = false;

  private resolve: Function|null = null;

  constructor() { this.reset(); }

  reset() {
    this.arrived = false;
    this.greeting = new Promise<string>((resolve, reject) => { this.resolve = resolve; });
  }

  clicked() {
    if (this.arrived) {
      this.reset();
    } else {
      this.resolve !('hi there!');
      this.arrived = true;
    }
  }
}

如您所见,this.resolve键入为Function|null。我们不能像this.resolve('hi there!')那样称呼它,否则TypeScript可能会抱怨,因为它可能是null

添加后缀!告诉编译器我们确定它不是null


侧注::我发现它们使用的格式有些奇怪。我个人会使用

this.resolve!('hi there!')

答案 1 :(得分:0)

非空声明操作符!通常用于外部代码实例化代码中的变量/字段的情况。假定启用了此检查的编译器选项strictNullChecks已打开。

通过外部代码设置功能时,有3种方法可以解决这种情况:

1)如果仅将函数定义为Function类型,则编译器会抱怨您在使用它之前没有实例化它。

class Example1 {
  // Error: Property 'getUsername' has no initializer and is not definitely assigned in the constructor.
  public getUsername: Function;

  public formatUsername(){
    return `Username is : ${this.getUsername()}`;
  }
}

在这种情况下,您可以在构造函数中添加虚拟初始函数,直到函数被外部​​代码替换:

class Example1a {
  public getUsername: Function;

  constructor(){
    this.getUsername = () => ""; // add dummy function, until it's replaced.
  }

  public formatUsername(){
    return `Username is : ${this.getUsername()}`;
  }
}

2)如果将其定义为Function | undefined类型,则编译器会抱怨您正在调用当时可能未定义的函数:

class Example2 {
  public getUsername: Function | undefined;

  public formatUsername(){
    // Error: Cannot invoke an object which is possibly 'undefined'.
    return `Username is : ${this.getUsername()}`;
  }
}

通常的解决方法是在调用函数之前检查函数是否确实未定义:

class Example2a {
  public getUsername: Function | undefined;

  public formatUsername(){
    // No Error: Check manually if function has been set.
    if (this.getUsername === undefined) {
      return "";
    }
    return `Username is : ${this.getUsername()}`;
  }
}

3)如果您确定可以通过外部代码设置功能(例如Angular的绑定),并且不想添加不必要的检查,则可以使用“!”。告诉编译器跳过对该特定函数调用的严格空检查。

class Example3 {
  public getUsername: Function | undefined;

  public formatUsername(){
    // No error: You tell compiler that `getUsername` won't be undefined.
    return `Username is : ${this.getUsername!()}`;
  }
}

打字稿游乐场link