基于泛型的条件方法参数

时间:2019-04-12 07:08:31

标签: typescript typescript-typings

我正在编写一个新的TypeScript类,该类具有一个通用值,该值将用作函数的输入。如果未提供值,则该函数不应接受任何输入。

理想情况下,此类会被重载。

class Emitter<T = void> {
    public activate(): void // When T is void
    public activate(arg: T): void // When T isn't void
    public activate(arg?: T) { /* ... */ }
}

将方法设为函数属性在理论上是可行的,但在方法的实现上需要@ts-ignore

type OneArgFn<T> = T extends void
    ? () => void
    : (arg: T) => void

interface Emitter<T> {
    readonly activate: OneArgFn<T>
}

另一种可能性是在是否提供泛型时导出不同的构造函数,例如以下

interface EmitterNoArg extends Emitter {
    activate: () => true
}
interface EmitterOneArg<T> extends Emitter<T> {
    activate: (arg: T) => void
}

interface EmitterConstructor {
    new(): Emitter

    new(): EmitterNoArg
    new<T>(): EmitterOneArg<T>
}

,但是要导出它,必须使用unknown关键字。

export default Emitter as unknown as EmitterConstructor

这些似乎不是最佳的。是否有适当的方法可以基于泛型的类型获取条件参数?我认为TypeScript的新conditional types将解决此问题。

1 个答案:

答案 0 :(得分:0)

一种方法是在单独的公共签名中的rest参数中使用元组:

type OneArgFn<T> = T extends void
    ? () => void
    : (arg: T) => void

class Emitter<T = void> {
    public activate(...a: Parameters<OneArgFn<T>>): void
    public activate(arg?: T) { /* ... */ }
}

new Emitter().activate();
new Emitter<string>().activate("") // in 3.4 argument names are preserved