我也想用一个函数扩展一个类,并制定了一个仅限 TypeScript 的解决方案。我不确定这是否是一个好主意,因为聪明的解决方案并不总是好的解决方案。 YMMV。
感谢 Mattias Buelens 提供部分答案!我正在构建它。
// same as in the answer of Mattias
interface Spy {
(foo: string, bar: number): boolean // Just an example
wasCalled(): boolean
}
// and now for the real solution!
class Spy {
_wasCalled: boolean
_baz: boolean // Just an example
private constructor(baz: boolean) {
this._wasCalled = false
this._baz = baz
}
wasCalled(): boolean {
return this._wasCalled
}
toString() { return '[object Spy]' }
static create(baz: boolean) {
const f = <Spy>function(this: Spy, foo: string, bar: number): boolean {
// Do your thing here. Use f instead of this!
console.log('wasCalled', f.wasCalled())
f._wasCalled = true
}
const spy = new Spy(baz)
Object.assign(f, spy)
Object.setPrototypeOf(f, Spy.prototype)
return f
}
}
这个想法是创建一个函数和Spy的实例,然后将原型和属性都分配给函数。从静态方法返回实例。一个好处是toString() 方法。
const spy = Spy.create(true)
console.log('calling spy', spy('foo', 42))
console.log('instanceof', spy instanceof Spy)
按预期工作。
我不认为new Spy() 会起作用,因为我们需要分配给一个函数,而不是反过来。而且因为我们不能替换 this 我们不能使 this 成为可调用的。我看到的一种假设方法是用真正的函数构造函数扩展一个类,如下所示:class Spy2 extends function() {} {},但我没有找到让它工作的方法。