使用调用签名和方法返回 "this" 实现接口
Implementing an interface with a call signature and method returning "this"
前言: 我们的团队正在开发一个基于 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]?经过研究,我发现了以下相关问题,所有这些问题都略有不同 and/or 相当古老。我想知道我们是否遗漏了什么,或者是否要在这里向 TypeScript 团队提出问题:
- How to make a class implement a call signature in Typescript?
请注意,接口对我们来说是外部的,因此实现它是我们唯一的选择。
¹ 为了这个问题,我希望实现明确重申所有类型注释。
在最新版本的 typescript(3.2 或 3.3 不确定是哪个)中,当您声明一个函数时,您还可以为该函数分配额外的属性,typescript 会将这些视为这些属性的定义,而不是抱怨它们已定义:
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
}
})
前言: 我们的团队正在开发一个基于 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]?经过研究,我发现了以下相关问题,所有这些问题都略有不同 and/or 相当古老。我想知道我们是否遗漏了什么,或者是否要在这里向 TypeScript 团队提出问题:
- How to make a class implement a call signature in Typescript?
请注意,接口对我们来说是外部的,因此实现它是我们唯一的选择。
¹ 为了这个问题,我希望实现明确重申所有类型注释。
在最新版本的 typescript(3.2 或 3.3 不确定是哪个)中,当您声明一个函数时,您还可以为该函数分配额外的属性,typescript 会将这些视为这些属性的定义,而不是抱怨它们已定义:
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
}
})