javascript TypeScript中的抽象静态方法

fnx2tebb  于 12个月前  发布在  Java
关注(0)|答案(2)|浏览(59)

我正在寻找一种在TypeScript中实现abstract static方法的方法。
下面是一个例子:

abstract class A {
  abstract static b (): any // error
}

class B extends A {
  static b () {}
}

publicprivateprotected方法允许这样做,但static方法不允许。TypeScript返回以下错误:
“static”修饰符不能与“abstract”修饰符一起使用。ts(1243)
是否有变通方法?

nhaq1z21

nhaq1z211#

我认为其理由大致如下:

  • 抽象方法是一个具体子类应该实现的占位符。
  • 抽象基类将有一个使用这个抽象占位符的具体方法,因此需要实现它;没有这些,抽象方法就没有什么意义。例如:
abstract class Foo {
    bar() {
        return this.baz() + 1;
    }

    abstract baz(): int;
}
  • 这只能在具体示例上调用,例如:
function (foo: Foo) {
    let val = foo.bar();
    ...
}

这里的结果会有所不同,这取决于您得到的Foo的具体子类,但它都保证可以工作。
现在,使用static方法会是什么样子?

abstract class Foo {
    static bar() {
        return this.baz() + 1;
    }

    abstract static baz(): int;
}

function (F: typeof Foo) {
    let val = F.bar();
    ...
}

这看起来有点合乎逻辑,好像它应该工作,不是吗?但是:

  • 如果您这样写,除了笨拙的typeof类型之外,传递类的示例基本上没有区别。那为什么
  • 如果你从不示例化类,那么类的意义何在?
  • 如果你的static方法 * 确实 * 示例化了一个对象,如果它充当了一个 * 替代构造函数 *--这是完全合法的--那么调用F.bar()来获取一个新的示例,**你会期望得到一个F的示例,**但你可能会得到它的某个子类的示例。这是不可取的。

在此重新表述一下这一论证链:

  • 如果您打算使用static方法,它们应该充当替代构造函数并返回一个示例,否则它们作为类的一部分就没有什么意义。
  • 替代构造函数应该返回调用它们的类的示例。调用F.bar()而没有得到一个完全是F的示例是......奇怪吗?
  • 如果你要在类上调用静态替代构造函数,你会想要在特定的类上调用它们,而不是如上所示的变量,因为否则你真的不知道你得到了什么(见上面的观点)。
  • 因此,abstract static方法没有真实的的用例,无论是作为直接的替代构造函数还是作为辅助函数,因为这将导致以某种方式违反上述任何一点。

据我所知,这几乎是导致abstract static方法不存在的经典思想。某些technical limitations in Java可能促成了这一点和/或首先导致了上述技术限制。
在JavaScript中,人们可以争辩说这没有什么意义,因为即使是类也是对象,并且如上所述使用它们是完全可行的,并且在某些情况下甚至可能有意义。但我们到了这里。

1mrurvl1

1mrurvl12#

我用下面的方法解决了这个问题:

interface Selectors<N> {
    selectName(node: N): string | undefined;
}

const selectors: Selectors<object> = {
    selectName(node: object) {
        return "my name is node";
    },
};

这显然与抽象静态类不同,但根据您要使用它做什么,这可能是一个很好的解决方案!

相关问题