打字稿抽象方法重载

Typescript abstract method overloading

我想在抽象 class 中重载抽象方法,如下所示:

abstract class Animal {

    public abstract communicate(sentence: string): void;
    public abstract communicate(notes: string[]): void;

}

class Human extends Animal {

    public communicate(sentence: string): void {
        // Do stuff
    }

}

class Bird extends Animal {

    public communicate(notes: string[]): void {
        // Do stuff
    }

}

然而,Typescript 给出了一个错误,指出我错误地扩展了基础 class(动物)

我做错了什么吗?就像期望根据 OOP 无论如何都会起作用的东西一样?还是 Typescript 不支持?

注意:参数的类型可以是完全不同的类型,与此示​​例不同。

那个抽象 class 期望实现两个方法签名。这两个方法签名是:

public abstract communicate(sentence: string): void;
public abstract communicate(notes: string[]): void;

它们可以这样实现:

class Human extends Animal {
    communicate(sentence: string); // optional overload signature
    communicate(notes: string[]);  // optional overload signature
    communicate(sentenceOrNotes: string | string[]) {
        // Do stuff
    }
}

最后的签名是实现签名。它需要与需要实现的方法签名兼容。

注意 Child 类

Child classes 需要与底座兼容,以便当您这样做时...

const animal: Animal = new Bird();

...child class 应该能够处理这两个调用:

animal.communicate("some sentence");
animal.communicate(["notes", "more notes"]);

在这种情况下,根据通信形式创建单独的接口可能更合适(或使用mixins):

interface CommunicatesWithSentences {
    communicate(sentence: string);
}

class Human extends Animal implements CommunicatesWithSentences {
    communicate(sentence: string) {
        // Do stuff
    }
}

就像@DavidSherret 所说的那样,sub-class 必须实现所有抽象 class 重载,而不仅仅是其中之一。所以你将无法真正使用抽象 class 重载来做你想做的事。

由于您想要 BirdHuman 具有不同的 communicate() 参数类型,由编译器强制执行,因此我将使用具有类型约束的泛型类型参数:

abstract class Animal<C extends string | string[]> {
    public abstract communicate(communication: C): void;
}

class Human extends Animal<string> {
    public communicate(sentence: string): void { }
}

class Bird extends Animal<string[]> {
    public communicate(notes: string[]): void { }
}

class Bynar extends Animal<boolean> { // Error: 'boolean' does not satisfy the constraint 'string | string[]'.
    public communicate(bit: boolean): void { }
}

const human = new Human();
human.communicate("hello"); // OK
human.communicate(["hello"]); // Error

const bird = new Bird();
bird.communicate("hello"); // Error
bird.communicate(["hello"]); // OK

提示:您也可以在这里使用 TS 2.3 default type arguments

这样就可以了,希望对大家有用

export abstract class BaseComponent {

     constructor(protected valueName: string) {

     }

     protected doSomethingMoreButOptional(config: IConfig): void { }

     protected doSomething() {
         if (valueName === 'derived') {
             this.doSomethingMoreButOptional(new Config());
         }
     }
}

export class DerivedComponent extends BaseComponent {

    private _xxx: any[];
    private _yyy: any[];

    constructor() {
        super('derived');
        super.doSomething();
    }

    protected doSomethingMoreButOptional(config: IConfig): void {
        switch (config.ABC) {
           case 'xxx':
              config.options = this._xxx;
              break;

           case 'yyy':
              config.options = this._yyy;
              break;

           default:
              return;
        }
    }
}