【问题标题】:Typescript "this-typing" confusion打字稿“this-typing”混淆
【发布时间】:2016-11-09 01:26:54
【问题描述】:

我指的是引用herehere的“this-typing”。

据我了解,使用 this 作为类型指的是当前类,或点的任何剩余部分(从而允许继承的方法引用它们自己的类而不是它们父类的类)。

那么有人可以解释为什么这不起作用:

class Test {
    children: Array<this>;

    constructor() {
        this.children = [new Test()];
    }
}

(我的目标是用继承的类来做到这一点,但它不适用于基类。既然thisTest 类型,为什么children 不能是Test 的数组?

【问题讨论】:

  • 无论如何,如果这可行,这将导致无限递归
  • 好点,我正在简化一个实际的代码示例并且做得很差。实际情况不会导致无限递归。

标签: typescript this


【解决方案1】:

不,当使用 this 作为类型时,您指的是实例而不是类。
它被称为 Polymorphic this types 并且应该像这样使用:

class Point {}

class Point2D extends Point {
    constructor(public x: number, public y: number) {
        super();
    }
}

class Point3D extends Point2D {
    constructor(x: number, y: number, public z: number) {
        super(x, y);
    }
}

class Builder2D {
    protected _x: number;
    protected _y: number;

    x(x: number): this {
        this._x = x;
        return this;
    }

    y(y: number): this {
        this._y = y;
        return this;
    }

    build(): Point {
        return new Point2D(this._x, this._y);
    }
}

class Builder3D extends Builder2D {
    private _z: number;

    z(z: number): this {
        this._z = z;
        return this;
    }

    build(): Point3D {
        return new Point3D(this._x, this._y, this._z);
    }
}

let p1 = new Builder3D().x(0).y(0).z(0).build();

(code in playground)

如果Builder2D.x()Builder2D.y() 将返回Builder2D

x(x: number): Builder2D {
    this._x = x;
    return this;
}

y(y: number): Builder2D {
    this._y = y;
    return this;
}

那么这将失败:

let p1 = new Builder3D().x(0).y(0).z(0).build();

与:

类型“Builder2D”上不存在属性“z”

在您的情况下,情况并非如此,您不想返回this
据我所知,this 的类没有类型,但你可以这样做:

class Test {
    public children: Array<Test>;

    constructor() {
        this.children = [new Test()];
    }
}

interface OtherTest {
    children: Array<OtherTest>;
}
class OtherTest extends Test {
    constructor() {
        super();
        this.children.push(new Test(), new OtherTest());
    }
}

let t1 = new Test();
let c1 = t1.children[0]; // typeof c1 is Test

let t2 = new OtherTest();
let c2 = t2.children[0]; // typeof c2 is OtherTest

(code in playground)


编辑

似乎有一个问题:Polymorphic "this" for static members

【讨论】:

    【解决方案2】:

    让我们定义派生类:

    class TestDerived extends Test {
        someMethod():void { }
    }
    

    正如您已经指出的那样 - this 的类型指的是当前类,因此 TestDerived 的成员 children 的类型为 TestDerived[]。所以我们可以这样做:

    let b = new TestDerived ();
    b.children[0].someMethod();
    

    如果 typescript 允许我们使用 Test 的实例填充这个数组(在 super 的构造函数中),我们将失去类型安全性(someMethod 未在 Test 中定义)。

    【讨论】:

      猜你喜欢
      • 2016-05-08
      • 2011-10-19
      • 2020-05-02
      • 1970-01-01
      • 2023-03-14
      • 2019-05-27
      • 2017-02-28
      • 1970-01-01
      • 2010-10-17
      相关资源
      最近更新 更多