【问题标题】:How to merge several object methods declared using generics in TypeScript?如何合并在 TypeScript 中使用泛型声明的多个对象方法?
【发布时间】:2018-11-21 20:08:08
【问题描述】:

范围

这就是我喜欢 TypeScript 的地方:

interface CommandBus {
    emit(type: 'execute', payload: { command: string }) : number;
    emit(type: 'stop', payload: { pid: number }) : bool;
}

…然后,当我写这篇文章时,commandBus.emit('stop', IntelliSense 会告诉我下一个函数参数是payload: { pid: number }。这是无价的!​​p>

也可以拆分成几个接口,TypeScript会合并,结果是一样的:

interface CommandBus {
    emit(type: 'execute', payload: { command: string }) : number;
}

interface CommandBus {
    emit(type: 'stop', payload: { pid: number }) : bool;
}

这是我用于我的应用程序的内容。在不同的包中,我使用特定于该包的方法扩展了一个接口。但是方法签名比上面那个更复杂,而且有更多通用的东西,所以我创建了泛型:

interface IEmit<TType, TPayload> {
    (type: TType, id: string, options: { payload: TPayload }) : void
}

我已经尝试在我的界面中使用它:

interface CommandBus {
    emit: IEmit<'execute', { command: string }>;
    emit: IEmit<'stop', { pid: number }>;
}

问题:TypeScript 无法处理这种语法,它只应用第一个 emit 声明并忽略其他声明。

问题:如何使用函数类型或接口重载接口中的方法?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    声明合并不能更改现有字段的类型(这是设计限制)。另一种解决方案是为 emit 字段声明一个类型并扩展它:

    interface IEmit<TType, TPayload> {
        (type: TType, id: string, options: { payload: TPayload }) : void
    }
    
    interface CommandBus {
      emit: CommandBusEmit;
    }
    
    //default type for the emit field 
    interface CommandBusEmit { }
    
    //extensions to it 
    interface CommandBusEmit extends IEmit<'execute', { command: string }> { }
    interface CommandBusEmit extends IEmit<'stop', { pid: number }> { }
    
    declare let cb: CommandBus;
    cb.emit('execute', "", { payload : { command: ""}})
    cb.emit('stop', "", { payload: { command: "" } }) // error
    cb.emit('stop', "", { payload : { pid: 1}}) // ok
    

    【讨论】:

      猜你喜欢
      • 2021-03-24
      • 2014-02-26
      • 2020-01-08
      • 2021-10-24
      • 2012-10-31
      • 1970-01-01
      • 1970-01-01
      • 2017-04-17
      • 2023-01-09
      相关资源
      最近更新 更多