实施泛型类型返回功能

时间:2018-03-21 03:35:58

标签: typescript generics

为了示例,假设我想编写一个函数,将日志记录添加到任何返回Promise的函数。在JS中我会做类似的事情:

const addLogging = (f) => (...args) => (
  f(...args).then(result => {
    console.log('result:', result);
    return result;
  })
)

const test = addLogging(
  (value) => Promise.resolve(value)
)

test('foo') // logs "​​​​​result: foo​​​​​"

现在我想用打字稿强制执行打字。以下是我提出的建议:

const addLogging = <F extends Function>(f: F): F => (
  (
    (...args: any[]) => (
      (f as any)(...args).then((result: any) => {
        console.log('result:', result);
        return result;
      })
    )
  ) as any
);

// Cool! :)
// type of test is (value: string) => Promise<string>
const test = addLogging(
  (value: string) => Promise.resolve(value),
);

// Less Cool :(
// Not valid, how to prevent it with typings?
const test2 = addLogging(
  (value: string) => value, // should return a promise
);

保留了增强函数的输入,这很好。但首先我必须使用大量any,并且我还要强制addLogging的{​​{1}}参数必须是返回f的函数。有什么简单的方法可以用打字稿吗?

1 个答案:

答案 0 :(得分:1)

您可以更加具体地了解F上的约束,您可以指定该函数接受任意数量的参数并返回Promise<any>

const addLogging = <F extends (...args: any[]) => Promise<any>>(f: F) => ((
  (...args) =>
    f(...args).then((result: any) => {
      console.log('result:', result);
      return result;
    })
) as F);

//Ok
const test = addLogging(
    (value: string) => Promise.resolve(value),
);

//Error
const test2 = addLogging(
    (value: string) => value, // should return a promise
);