我不确定如何创建一个通常会将行为添加到另一个函数的函数。这就是我要做的事情:
/**
* Creates a function that calls originalFunction, followed by newFunction.
* The created function returns the value returned by the original function
* returned by the original function
* @param originalFunction Function to be called first
* @param newFunction Function to be called second
*/
function callAfter<T extends Function>(originalFunction: T, newFunction: T): any {
return function() {
const result = originalFunction.apply(this, arguments);
newFunction.apply(this, arguments);
return result;
};
}
上述内容并未使用以下消息进行编译
TS2322:输入&#39;()=&gt;任何&#39;不能分配给&#39; T&#39;
我能做些什么来保持类型安全吗?现在我有了它&#34;工作&#34;让它返回any
我进一步尝试了,并提出以下
/**
* Creates a function that calls originalFunction, followed by newFunction. The created function returns the value
* returned by the original function
* @param originalFunction Function to be called first
* @param newFunction Funct
*/
function callAfter<R, T extends () => R>(originalFunction: T, newFunction: T): T {
return <T> function () {
const result: R = originalFunction.apply(this, arguments);
newFunction.apply(this, arguments);
return result;
};
}
这个问题是它对于返回void的函数不起作用(这是我此刻真正关心的用例)
这是我尝试编写的代码,但希望使用通用的高阶函数来扩展功能。
/**
* Component can use this to have subscriptions automatically
* removed when the component is removed from the DOM
*/
class SubscriptionTracker {
private subscriptions: Subscription[] = [];
constructor(destroyable: OnDestroy) {
destroyable.ngOnDestroy = callAfter(destroyable.ngOnDestroy, () => {
this.subscriptions.forEach((subscription) => subscription.unsubscribe());
});
}
subscribe<T>(observable: Observable<T>, observer: PartialObserver<T>): Subscription {
const subscription = observable.subscribe(observer);
this.subscriptions.push(subscription);
return subscription;
}
unsubscribe(subscription: Subscription) {
subscription.unsubscribe();
const indexOfSubscription = this.subscriptions.indexOf(subscription);
if (indexOfSubscription == -1) {
throw new Error('Unsubscribing to untracked subscription');
}
this.subscriptions.splice(indexOfSubscription, 1);
return subscription;
}
}
答案 0 :(得分:0)
据我所知,你只需要对返回类型和参数有更好的约束。我们可以为每个函数定义一个适当的函数类型,而不是让仿函数采用相同类型T
的两个函数。
function callAfter<O>(f: (...any) => O, f2: (...any) => void): (...any) => O {
return (...args) => {
let r = f(...args);
f2(...args);
return r;
}
}
一些例子:
function double(x) { return x + x; };
function yell(x) {
console.log(`${x}!!!`);
}
let doubleLoud = callAfter(double, yell);
let x = doubleLoud(4501);
console.log(`doubleLoud(4501) = ${x}`);
它也适用于在任何一方返回void的函数,甚至包含多个参数的函数:
callAfter(yell, yell)("Ni");
let lreluLoud = callAfter(function lrelu(x, alpha) {
if (x < 0) x *= alpha;
return x;
}, yell);
console.log(`lreluLoud(-20, 0.2) = ${lreluLoud(-20, 0.2)}`);