繁体   English   中英

Typescript getter 类型推断

[英]Typescript getter type inference

Typescript 似乎严格根据字段的私有变量推断字段类型。 但是,如果 getter 返回类型联合 (1),它不会抱怨,也不会从 getter (2) 推断实际类型:

    test('field type inference', () => {
  class A {
    x_: number;

    // 1: no type checking here
    get x(): number | undefined {
      if (this.x_ === 1) return undefined;
      return this.x_;
    }

    set x(v: number | undefined ) {
      this.x_ = +v;
    }
  }

  const a = new A();
  a.x = 1;

  // 2: The inferred type is number (as of x_, instead of getter)
  const x: number = a.x;

  console.log(a.x) // outputs 'undefined'
})

这是指定/预期的行为吗?

后来编辑。 请注意, strictNullCheck也不会捕捉到这一点。 唯一缺少初始化和设置器的两个

以下示例修复了strictNullCheck警告:

test('field type inference', () => {
  class A {
    x_: number;

    get x(): number | undefined {
      if (this.x_ === 1) return undefined;
      return this.x_;
    }

    set x(v: number | undefined ) {
      this.x_ = +(v ?? 0);
    }

    constructor(value: number) {
      this.x_ = value;
    }
  }

  const a = new A(2);
  a.x = 1;

  const x: number = a.x;

  console.log(a.x)
});

首先,当您拥有属性时,打字稿假定从属性读取将检索最后写入该属性的值。 你在这里的 getter/setter 打破了这个约定。 但是因为每个 get/set 函数在技术上都是类型安全的,所以 typescript 不会发现任何错误。

其次,当您将常量分配给类型为联合的属性时,打字稿会记住该联合的哪个成员适用于该范围的其余部分。 你在这些 getter/setter 中有逻辑的事实并不重要。

它与私有财产无关,而与公共财产有关。

假设您有一个非常简单的类:

// No getters/setters
class B {
  x: number | undefined
}

const b = new B()
b.x // number | undefined
b.x = 1
b.x // number

如您所见,打字稿会记住您分配的内容,知道它不是未定义的,然后从属性的结果类型中删除它可以知道的任何地方。


现在让我们试试这个类:

// useless getters/setters
class C {
  get x(): number | undefined {
    return undefined;
  }

  set x(v: number | undefined ) {
    // no-op
  }
}

const c = new C()
c.x // number | undefined
c.x = 1
c.x // number

现在 getter/setter 没用了,但它给了你“错误”的结果。

操场


如果最后一个值是在同一个同步执行范围内设置的,Typescript 期望 getter 返回最后一个设置值。 事实上,大多数程序员也可能会这样做。

理想情况下,编译器会在这里标记某个问题,但通过这些 setter 跟踪类型安全实际上是一件非常复杂的事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM