TypeScript接口中的覆盖/覆盖方法签名

在这个特定的例子中,我正在扩展 Array<T> 接口,如下所示:

interface BetterArray<T> extends Array<T> {
    push(this: BetterArray<T>, value: T): this;
}

注意供参考 - Array<T>.push 是这样实现的

interface Array<T> {
    push(...items: T[]): number;
}

但是我得到以下编译时错误:

接口'BetterArray'错误地扩展了接口'T []' . 属性“推”的类型是不兼容的 . 输入''(this:BetterArray,value:T)=>此''不能分配给''(items:T [])=> number' . 输入“this”不能指定为“number”类型 . 类型'BetterArray'不能分配给'number'类型 .

有什么方法可以强制指示TypeScript,我想覆盖我的界面上的推送(如member hiding in C#)?

Note - I'm using TypeScript 2.0

进一步阅读 - 看来这纯粹归结为返回类型 - 基本上我想通过接口强制执行,一个新的返回类型......

interface A {
    fn(): number;
}

interface B extends A {
    fn(): this;
}

接口'B'错误地扩展了接口'A' . 属性'fn'的类型是不兼容的 . 输入'()=> this'不能赋值为'()=> number' . 输入“this”不能指定为“number”类型 . 类型“B”不能分配给“数字”类型 .

回答(2)

2 years ago

您只需要添加 Array.push 的原始签名:

interface BetterArray<T> extends Array<T> {
    push(...items: T[]): number;
    push(this: BetterArray<T>, value: T): this;
}

你要做什么的问题是如果 thisBetterArray 那么你不能返回 this ,例如:

class BetterArrayClass<T> extends Array<T> {
    push(...items: T[]): number;
    push(this: BetterArrayClass<T>, value: T): this;
    push(this: BetterArrayClass<T>, ...items: T[]): number | this {
        return this;
    }
}

错误:

类型'BetterArrayClass'不能分配给'number |这个' . 类型'BetterArrayClass'不能指定为'this'类型 . 这个:BetterArrayClass

在这个更简单的例子中可以看到原因:

class A {
    fn(this: A, num: number): this {
        return this; // Error: Type 'A' is not assignable to type 'this'. this: A
    }
}

class B extends A {
    fn(num: number): this {
        if (num < 0) {
            return super.fn(num);
        }
        return this;
    }
}

如果在 B.fn 中我们正在调用 super.fn ,则 this 不是 A 而是 B ,并且在任何情况下我们都想返回 B 的实例 .
这不是 A.fn 所描述的 .

2 years ago

根据nitzan tomer's | answer

您只需要添加Array.push的原始签名:

interface BetterArray<T> extends Array<T> {
    push(...items: T[]): number;
    push(this: BetterArray<T>, value: T): this;
}

使用 never 类型似乎适用于此 . Intellisense选择 never ,“ never ”返回,所以不打扰向你显示方法签名(整齐)

interface BetterArray<T> extends Array<T> {
    push(...items: T[]): never;
    push(this: BetterArray<T>, value: T): this;
}