在 TypeScript 的 class 方法中使用类型谓词

Using type predicates in class methods in TypeScript

我有一个 class 定义如下

class Foo {
   value: string | null;
   constructor(){
      this.value = null;
   }
   private ensureValueExists():this.value is string{ //type predicate is not legal
      this.value = "bar";
      return true;
   }
   doStuffWithValue(){
      this.ensureValueExists();
      return 5 + this.value;  //ERROR, this.value can be null
   }
} 

我希望 ensureValueExists 方法能够告诉编译器 this.value 确实是一个字符串并且可以安全使用。 是否有特殊的语法可以使用,或者目前 TS 无法用于方法?

此语法称为 user-defined type guard。它可用于缩小其参数的类型,但除此之外别无他法。例如,即使这个代码也行不通:

let value: unknown

function isValueString(): value is string { // Cannot find parameter 'value'.
    return typeof value === 'string'
}

Playground link

还有 assertion function 语法,您最初可能打算使用它。但是,这与上面的限制相同,你不能在函数参数以外的任何地方使用它:

let value: unknown

function ensureValueIsString(): asserts value is string { // Cannot find parameter 'value'.
    value ??= 'bar'
}

Playground link

您可以使用 assertion method which narrows this. Support for that isn't particularly clear from the documentation, although a commit associated with microsoft/TypeScript#32695,PR 实现断言函数,证明这是可能的。

所以在你的情况下它看起来像:

  private ensureValueExists(): asserts this is { value: string } {
    this.value = "bar";
  }

(请注意,您不能在断言 function/method 中 return 任何内容),然后以下工作:

  doStuffWithValue() {
    this.ensureValueExists();
    return 5 + this.value;  // okay
  }
}

肯定有 caveats 与断言函数和方法相关联,但由于您只在 this 上操作,因此您 运行 不在这里。

Playground link to code