在TypeScript

时间:2019-06-09 07:55:48

标签: typescript

在TypeScript中,我想使用看起来像这样的模式:

Two pairs of an interface & static helper, where the interfaces have an inheritance relation but the static helpers don't

所有FooBar<T>的类型也都是Bar<T>,我想在类型系统中表达这一点。但是,我也希望能够编写诸如Bar.create<T>(...)FooBar.create<T>(...)之类的静态方法,而这些函数之间没有任何关系。将属性添加到Bar<T>类型应强制所有FooBar<T>也包含该属性,但是向静态Bar添加方法应强制该方法执行以下操作:出现在FooBar中。

在C#中,我只是拥有interface IBar<T>static class Bar,但是为了符合TypeScript的命名约定,我希望显示的名称,除非没有其他选择。

这是我的第一次尝试,导致出现错误“'Bar'的所有声明必须具有相同的类型参数”:

interface Bar<T> {
    readonly x: T;
}

class Bar {
    static create<T>(x: T) : Bar<T> {
        return { x: x };
    }
}

在这里也可以接受类,所以我的第二次尝试是:

class Bar<T> {
    static create<T>(x: T) {
        return new Bar(x);
    }

    static barOnly() { }

    constructor(public readonly x: T) { }
}

class FooBar<T> extends Bar<T> {
    static create<T>(x: T, y: T) {
        return new FooBar<T>(x, y);
    }

    constructor(x: T, public readonly y: T) {
        super(x);
    }
}

不幸的是,看起来FooBar试图继承Bar的静态成员,所以我不仅以不受欢迎的FooBar.barOnly结尾,而且甚至没有编译,因为“'{typeof FooBar'的类静态侧错误地扩展了基类静态'typeof Bar'”,因为create的类型不兼容。

是否有任何方法可以继承“接口侧”,而无需“静态侧”?我怀疑一定有,因为TS似乎非常擅长捕获所有人们在JavaScript中所做的事情很奇怪,我可以在原始JavaScript中得到想要的东西。下面的代码具有我想要的所有属性,当然,除了TypeScript的强类型外:

function Bar(x) {
    this.x = x;
}

Bar.create = x => new Bar(x);

Bar.prototype.getX = function () {
    return this.x;
}

function FooBar(x, y) {
    Bar.call(this, x);
    this.y = y;
}

FooBar.create = (x, y) => new FooBar(x, y);

FooBar.prototype = Object.create(Bar.prototype);

FooBar.prototype.getY = function () {
    return this.y;
}

2 个答案:

答案 0 :(得分:1)

您可以在派生类的library(reshape) df <- merge(path, expr, by = "gene", all=T) df <- t(cast(gene ~ pathway, data=df)) df <- df[-which(rownames(df) == "NA"),] df[is.na(df)] <- 0 df 子句中使用类型声明,以实质上擦除类型的静态部分。

不确定这是否不会导致其他问题,但它似乎可以工作:

extends

答案 1 :(得分:0)

除了Titian回答如何使用类进行工作外,我还能够通过将“静态”帮​​助器放入与接口同名的自己的对象中,从而完全通过接口来完成此任务:

interface Bar<T> {
    readonly x: T;
}

const Bar = {
    create: function <T>(x: T): Bar<T> {
        return { x: x };
    },
    barOnly: () => { }
};

interface FooBar<T> extends Bar<T> {
    readonly y: T;
}

const FooBar = {
    create: function <T>(x: T, y: T): FooBar<T> {
        return { x: x, y: y };
    }
}