通过调用签名和返回“ this”的方法实现接口

时间:2019-03-27 11:13:48

标签: typescript definitelytyped

前言:我们的团队正在开发基于d3的库。由于我们使用的是TypeScript,因此我们也使用了DefinitelyTyped中的d3类型。尝试使用ScaleOrdinal等接口和其他接口时,会出现以下问题。


假设我们有一个既包含呼叫签名又包含其他属性的接口:

export interface Foo<T> {
    // Let's pretend this will be the identity function
    (arg: T): T;

    // Let's pretend that this will be a no-op function
    // Note that this returns "this"    
    doFoo(): this;
}

我们如何正确且以类型安全的方式实现这样的接口[1]?经过研究,我发现了以下相关问题,所有这些问题都略有不同和/或相当古老。我想了解一下我们是否遗漏了一些东西,或者是否向TypeScript团队提出了问题:

  1. How to make a class implement a call signature in Typescript?
  2. TypeScript: Implement interface with both call signature and constructor signature
  3. TypeScript: Implement an interface with both call signature and indexing signature

请注意,该接口在我们外部,因此实现它是我们唯一的选择。


¹出于问题的考虑,我希望该实现显式地重新声明所有类型注释。

1 个答案:

答案 0 :(得分:1)

在最新版本的打字稿(3.2或3.3版本不确定)中,当您声明一个函数时,还可以为该函数分配额外的属性,打字稿会将这些属性视为这些属性的定义,而不必抱怨它们没有被使用过定义:

export interface Foo<T> {
    (arg: T): T;  
    doFoo(): this;
}

function foo(arg: number) : number {
    return arg
}
foo.doFoo = function <TThis extends typeof foo>(this: TThis): TThis { // no polymorphic this in simple functions
    return this
}

let o: Foo<number> = foo;  // foo is compatible with Foo<number>

以前是这样做的,但仍然可以使用Object.assign创建具有额外属性的函数:

let o: Foo<number> = Object.assign(function (arg: number): number {
    return arg
}, {
    doFoo: function <TThis>(this: TThis): TThis {
        return this
    }
})