在子类或接口上定义的Typescript专用重载

有没有办法进行以下工作而不必在子类中定义一个简单地调用超类或不必要地重复非专用签名的实现?

class Emitter {
    on(name: 'one', handler: (value: number) => void): void;
    on(name: string, handler: (...args: any[]) => void): void;
    on(name: string, handler: (...args: any[]) => void): void { 
        // do stuff
    }
}


class Subclass extends Emitter {
    on(name: 'two', handler: (value: string) => void): void;
    on(name: string, handler: (...args: any[]) => void): void;
    // error no implementation specified
}


interface IEmitter {
    on(name: 'one', handler: (value: number) => void): void;
    on(name: string, handler: (...args: any[]) => void): void;
}


interface ISubclass extends IEmitter {
    on(name: 'two', handler: (value: string) => void): void;
    // error overload not assignable to non specialized
}

最佳答案 如果函数重载是对象类型上的调用签名,则它们才会合并.最简单的修复(对于接口情况)是将函数类型分离到它自己的接口并扩展它:

interface EmitterEvent {
    (name: 'one', handler: (value: number) => void): void;
    (name: string, handler: (...args: any[]) => void): void;
}

interface SubclassEmitterEvent extends EmitterEvent {
    (name: 'two', handler: (value: string) => void): void;
}

interface IEmitter {
    on: EmitterEvent;
}

interface ISubclass extends IEmitter {
    on: SubclassEmitterEvent;
}

var x: ISubclass;
x.on('one', n => n.toFixed()); // n: number
x.on('two', s => s.substr(0)); // s: string
var y: IEmitter;
y.on('two', a => a); // a: any

类案例中的等价版本需要一些工作(假设您关心原型上的函数 – 如果没有,只需使用函数表达式作为初始化器):

class Emitter {
    on: EmitterEvent;
}
module Emitter {
    Emitter.prototype.on = function(name: string, handler: any) {
        // Code here
    }
}
点赞