在 TypeScript 中建模类型层次结构的最实用方法

问题描述 投票:0回答:1

我有一个抽象基本类型和它的一堆子类型。有些子类型本身是抽象的,并且还有更多的子类型。

我希望能够定义多态函数,其中一些可能是抽象的,而另一些则具有可能被某些节点重载的默认实现。

在 TypeScript 中对此进行建模的最佳方法是什么?

在 JavaScript 中我会使用

class
es。这是一个愚蠢而简单的例子,它展示了我要写的内容。请不要担心语义,只需担心我正在尝试建模的数据类型。

class Polygon {
    constructor( name ) { this.name = name; }
    // abstract methods
    area() { assert.fail(`${this.constructor.name} must implement area()`); }
    // methods with fallback implementation
    toString() {
        const props = Object.entries(this)
            .filter( ([k, v])=>k !== 'name' )
            .map( ([k, v])=>`${k}:${v}` )
            .join(", ");
        return `${this.name}{props}`;
    }
}
class Triangle extends Shape {
    constructor( base, height ) {
        super('TRIANGLE');
        this.base = base;
        this.height = height;
    }
    area() { return this.base*this.height/2; }
}
class Quadrilateral extends Shape {
    constructor( name, base, height ) {
        super(name);
        this.base = base;
        this.height = height;
    }
    area() { return this.base*this.height; }
}
class Square extends Quadrilateral {
    constructor( side ) {
        super( 'SQUARE', side, side );
    }
    area() { return this.base*this.height; }
    toString() { return `${this.name}{side:${this.base}}`; }
}

然而,以简单的方式在 TypeScript 中转换这个东西效果不太好:

  1. 字段

    name
    不能用作
    Polygon
    的判别式。如果我想使用正确的判别式,我必须引入:
    type PolygonType = Triangle | Square;
    并使用
    PolygonType
    而不是
    Polygon
    作为其未知子类型的类型。

  2. 使用

    class
    限制了我的表达能力。例如,我无法使用类型级元编程来帮助我定义类型的确切形状。

更适合 TypeScript 的实现是使用

type
对我的类型进行建模。但这意味着放弃通过原型继承实现的多态性,以及 JavaScript
class
es 的所有其他好处。

我想知道是否有其他解决方案来解决类似的问题,我预计这将是非常常见的,以及是否有任何解决方案是普遍首选的。

javascript typescript inheritance polymorphism subtyping
1个回答
0
投票

在这种情况下,使用 interfaces 而不是类型似乎是有益的。

首先,接口指定了类型,这样目的就达到了。

另一方面,接口从字面上和历史上看都是一个抽象类,没有单个实现的方法。

因此,如果它是一个类,则可以像类一样进行扩展以实现多态目的:

interface Shape {
  area(): number
}
interface Polygon extends Shape {
  toString(): string
}


class Triangle implements Shape {}
class Square implements Polygon {}

© www.soinside.com 2019 - 2024. All rights reserved.