Typescript - 扩展外部Javascript库

时间:2016-05-18 10:43:58

标签: typescript

我正在构建一个Typescript应用程序,我正在使用外部js库(pixi.js用于渲染)。我有.d.ts文件,而且一切正常。

该文件声明了一个类Point:

export class Point {

    x: number;
    y: number;

    constructor(x?: number, y?: number);

    clone(): Point;
    copy(p: Point): void;
    equals(p: Point): boolean;
    set(x?: number, y?: number): void;

}

我想知道是否有任何可行的方法来为这个或其他在.d.ts文件中声明的类添加功能。例如,在这种情况下,我真的可以使用add(),subtract(),negate()方法等。

编辑:为了澄清,我不想通过创建子类来扩展这个类。我想为类本身添加功能。我不想在我的代码中处理两个类(例如Point和PointEx) - pixi在内部使用Point并经常从函数返回它,因此我不希望将Point转换为扩展对象的额外开销。

1 个答案:

答案 0 :(得分:7)

您可以像使用任何其他类一样扩展该类:

class MyPoint extends Point {
    private name: string;

    constructor(name: string, x?: number, y?: number) {
        super(x, y);

        this.name = name;
    }

    public getName() {
        return this.name;
    }

    public add(other: Point): Point {
        return new Point(this.x + other.x, this.y + other.y);
    }
}

修改

您可以使用原型扩展它,如下所示:

interface Point {
    add(other: Point): Point;
}

Point.prototype.add = function(other: Point): Point {
    return new Point(this.x + other.x, this.y + other.y);
}

第一部分(带有界面)被称为Declaration Merging,当您为现有类型添加更多定义时,它就会被调用。
另一部分是函数的实现并将其添加到Point.prototype

虽然这有效,但我不推荐它:
基础Point不受您的控制,如果明天他们更改它并添加他们自己的add方法,其签名与您的签名不同,会发生什么?因此,您将被迫更改整个代码库。

你可以用你自己的点类(扩展基类)来做一个基础上的ctor:

class MyPoint extends Point {
    constructor(base: Point) {
        super(base.x, base.y);

        // ...
    }
}

或者,将工厂方法添加到Point.prototype

interface Point {
    toMyPoint(): MyPoint;
}

Point.prototype.toMyPoint = function(): MyPoint {
    return new MyPoint(this);
}

这两种方式都可以让您方便地从MyPoint中获取Point作为执行结果而获得的结果。