引用没有名称的类以在 TypeScript 的子类中使用不同的静态方法

Sha*_*aun 7 typescript typescript1.8

在 ES6 中,您可以通过this.constructor以下方式引用静态方法:

class MainClass {
  static info() {
    return "This is some information";
  }
  constructor() {
    this.info = this.constructor.info(); // Allows subclass to define different '.info()' method.
  }
}

class ChildClass extends MainClass {
  static info() {
    return "This information is from the child";
  }

  constructor() {
    super();
  }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法在 TypeScript 中做到这一点?我希望能够覆盖超类的静态方法并从子类中使用它,而无需在实例方法中重新定义引用。现在,我知道如何在 TypeScript 中访问静态方法的唯一方法是使用类名。

MainClass.info();
Run Code Online (Sandbox Code Playgroud)

但是如果我这样做,子类将继续使用MainClass.info();而不是它自己的.info()方法。

Nit*_*mer 5

这个怎么样:

interface MainClassConstructor {
    new (): MainClass;
    info(): string;
}

class MainClass {
    static info() {
        return "This is some information";
    }

    private info: string;

    constructor() {
        this.info = (this.constructor as MainClassConstructor).info(); // Allows subclass to define different '.info()' method.
    }
}

class ChildClass extends MainClass {
    static info() {
        return "This information is from the child";
    }

    constructor() {
        super();
    }
}
Run Code Online (Sandbox Code Playgroud)

操场上的代码


编辑

你也可以使用我添加的接口typeof MainClass来代替MainClassConstructor

class MainClass {
    static info() {
        return "This is some information";
    }

    private info: string;

    constructor() {
        this.info = (this.constructor as typeof MainClass).info(); // Allows subclass to define different '.info()' method.
    }
}
Run Code Online (Sandbox Code Playgroud)

此外,this.constructor这里还有一个关于返回正确类型的讨论/建议:T.constructor 应该是 T 类型

另一种选择是使用方法重写:

class MainClass {
    private info: string;

    constructor() {
        this.info = this.getInfo();
    }

    protected getInfo(): string {
        return "This is some information";
    }
}

class ChildClass extends MainClass {
    constructor() {
        super();
    }

    protected getInfo(): string {
        return "This information is from the child";
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在面向对象中,您通常会避免重写静态方法,静态成员/方法的整个概念并不是非常面向对象。在我的最后一个代码块中,我在父类中仅设置一次“info”成员,但它从“getInfo”方法获取的值,然后您可以在子类中重写该值。我不喜欢更改父级在子类中设置的值,这很容易出错。使用这个“getInfo”方法,只有一个地方可以进行赋值。 (2认同)

dpo*_*sch 4

查看此打字稿代码:

class MainClass {
  static info() {
    return "This is some information";
  }
  info: string;

  constructor() {
    this.info = (this.constructor as any).info(); // Allows subclass to define different '.info()' method.
  }
}

class ChildClass extends MainClass {
  static info() {
    return "This information is from the child";
  }

  constructor() {
    super();
  }
}
Run Code Online (Sandbox Code Playgroud)

如果编译目标是 ES6,它将编译为精确的上面给出的代码并且工作正常。如果编译成 ES5,它也可以正常工作。

请注意,我使用了as anyhack 来允许调用.info() constructor 函数。

this.info或者,您可以覆盖每个子类中的设置。这样你就不需要黑客了。