简体   繁体   English

Typescript 用通用类型包装 function

[英]Typescript wrapping function with generic type

How can I wrap a function without changing its generic type in Typescript?如何在不更改 Typescript 中的通用类型的情况下包装 function?

function x() {
  console.log('Original Function');
}

function wrapper<T extends Function>(func: T): T {
  // Typescript compiler error:
  // Type '() => void' is not assignable to type 'T'.
  return () => {
    console.log('Wrapped Function');
    func.call(null);
  }
}

const xWrapped = wrapper(x);
xWrapped(); // logged 'Wrapped Function' & 'Original Function'

How can I wrap a function without changing its generic type in Typescript?如何在不更改Typescript中泛型类型的情况下包装函数?

function x() {
  console.log('Original Function');
}

function wrapper<T extends Function>(func: T): T {
  // Typescript compiler error:
  // Type '() => void' is not assignable to type 'T'.
  return () => {
    console.log('Wrapped Function');
    func.call(null);
  }
}

const xWrapped = wrapper(x);
xWrapped(); // logged 'Wrapped Function' & 'Original Function'

How can I wrap a function without changing its generic type in Typescript?如何在不更改Typescript中泛型类型的情况下包装函数?

function x() {
  console.log('Original Function');
}

function wrapper<T extends Function>(func: T): T {
  // Typescript compiler error:
  // Type '() => void' is not assignable to type 'T'.
  return () => {
    console.log('Wrapped Function');
    func.call(null);
  }
}

const xWrapped = wrapper(x);
xWrapped(); // logged 'Wrapped Function' & 'Original Function'

I prefer a simpler solution, like bellow:我更喜欢更简单的解决方案,如下所示:


function wrapFunction<TArgs extends any[], TReturn>(
  targetFunction: (...parameters: TArgs) => TReturn,
): (...parameters: TArgs) => TReturn {
  return (...parameters: TArgs) => {
    console.log(`Hello, what is your name?`);
    return targetFunction(...parameters);
  };
}


// --------------- Example
const someFunction = (name: string) => {
    console.log(`Hey! My name is ${name}.`);
}

const wrappedFunction = wrapFunction(someFunction);
wrappedFunction("Fábio");

Output输出

[LOG]: "Hello, what is your name?" 
[LOG]: "Hey! My name is Fábio." 

Or, if you want something more generic:或者,如果你想要更通用的东西:

export function wrapFunction<TArgs extends any[], TReturn>(
  targetFunction: (...parameters: TArgs) => TReturn,
  wrapperFunction: (...parameters: TArgs) => void,
): (...parameters: TArgs) => TReturn {
  return (...parameters: TArgs) => {
    wrapperFunction(...parameters);
    return targetFunction(...parameters);
  };
}



// --------------- Example
const someFunction = (name: string) => {
    console.log(`Hey! My name is ${name}.`);
}

const wrapperFunction = (name: string) => {
    console.log(`The wrapper - Hey! My name is ${name}.`);
}

const wrappedFunction = wrapFunction(someFunction, wrapperFunction);
wrappedFunction("Fábio");

Output输出

[LOG]: "The wrapper - Hey! My name is Fábio." 
[LOG]: "Hey! My name is Fábio."

Here's another way I found.这是我发现的另一种方式。 It keeps even the generics of the wrapped function:它甚至保留了包装的 function 的 generics:

const newFunction = ((one, two) => {
    // something before
    const result = oldFunction(one, two)
    // something after
    return result
}) as typeof oldFunction

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM