【问题标题】:TypeScript not inferring type from class method return valueTypeScript 不从类方法返回值推断类型
【发布时间】:2021-09-25 16:58:47
【问题描述】:

我在写一个类,在构造函数中,类类调用了它的一个方法toJSON,并将返回值赋给一个实例属性:

class Example {
  property;
  snapshot;

  constructor(){
    this.property = 'property'

    if (Math.random() < 0.5){
      this.snapshot = this.toJSON()
    }
  }

  toJSON(){
    return {
      this: 'this',
      is: 'is',
      a: 'a',
      sample: 'sample',
      json: 'json'
    }
  }

  useSnapshot(){
    console.log(this.snapshot?.nope)
  }
}

在我处理这个问题时,toJSON 的返回值的形状可能会改变,所以我不想硬编码返回类型。但是,我希望打字稿能够推断出返回类型并强制执行。所以上例中this.snapshot.nope会报错,因为nopetoJSON的返回类型上不存在,因此this.snapshot上也不存在。 This typescript playground 显示预期的行为。

但在我的代码中,返回类型从未正确分配给snapshot - 它保持为any 类型。尽管上面的示例简化了相关部分,但代码很复杂且难以重现。然而,我的智能感知显示了一个不同的故事。

悬停在toJSON 上会显示正确的推断类型:

悬停在snapshot 上显示类型any

在整个代码中,在任何使用MyClass.snapshot 的地方,智能感知都会将其转换为any,因此如果我对该对象执行了不正确的操作,我不会得到任何类型提示或错误。我不确定从哪里开始调试它,因为我的代码是上面示例的更复杂的版本。我正在使用 TS 版本 4.3.5。我可以从哪里开始调试?

【问题讨论】:

  • 这是因为变量被初始化为任何类型。您不能更改变量类型。
  • 如果是这样,那么我发布的示例将不起作用
  • 您是否尝试过明确键入snapshot 属性? snapshot: ReturnType&lt;TimeStep["toJSON"]&gt; | undefined。无论哪种方式,如果没有可重现的示例,我们将无法进行调试。
  • 在我使用节点打字稿时使用您的示例,我没有任何类型错误,但是当我使用 deno 时,我有类型错误。 IntelliSense 可能是您的问题。
  • @lawrence-witt ReturnType 正是我所希望的。将snapshot 显式输入为ReturnTypetoJSON 效果很好。如果您将其发布为答案,我会将其标记为答案。

标签: typescript class type-inference


【解决方案1】:

正如cmets中提到的,我们可以使用ReturnType来动态获取任何函数的返回类型。类成员也可以通过类型索引访问:

class TimeStep {
  snapshot: ReturnType<TimeStep["toJSON"]>;

  ...

  toJSON() {
    return {}; // implementation
  }
}

我不知道为什么您的环境不能自动执行此操作,但结果类型检查是相同的。这可能更具描述性。

【讨论】:

    猜你喜欢
    • 2011-01-13
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    • 2017-03-08
    • 2018-02-22
    • 1970-01-01
    相关资源
    最近更新 更多