【问题标题】:Typescript: use ReturnType of array of functions (edited)打字稿:使用函数数组的 ReturnType(已编辑)
【发布时间】:2021-03-10 07:09:11
【问题描述】:

我正在尝试键入以下函数:

function foo(input, modifier, merge) {
    return merge(...modifier.map(m => m(input)));
}

目标是为merge 函数的参数提供正确的类型。

上下文:

  • modifier 是一个函数数组,具有 typeof input 类型的单个参数和每个函数的不同返回类型
  • merge是一个函数,它有modifier.length参数,位置n的参数与函数modifier[n]的返回类型相同,并返回一个单一(通用)值

如何做到这一点?


编辑:替代问题

可以使用对象 (Record<K,V>):

// for Functions (here type Func)
type Func = () => any;

// a mapping of a string key to an function can be created
type FuncMap = Record<string, Func>;

// for this mapping you can create a mapping to the return types of each function
type ReturnTypeMap<T extends FuncMap> = { [K in keyof T]: ReturnType<T[K]> }

基于位置而不是对象键的数组是否也可以这样做?


这是我在键入函数时的尝试,但我不知道如何将 ReturnType 与数组结合使用:

function foo<I, M extends Array<(input: I) => any>, O>(
    input: I,
    modifier: M,
    merge: (...args: ReturnType<M>) => O
    //               ^^^^^^^^^^^^^ this is not working, since relation to each item is missing
): O {
    return merge(...modifier.map(m => m(input)));
}

【问题讨论】:

  • modifier 应该是什么?一系列函数,但它们应该是吗? merge 是什么?
  • 更新问题以澄清 modifiermerge
  • 好的,所以你可以有类似input = "foo" 的东西,它们modifier.map(m =&gt; m(input)) 可能会产生,比如[42, "bar", true]merge 函数应该接受所有这些并产生一些单一的值。如果我正确阅读了描述,在这个例子中,merge 应该产生boolean,因为这是最后一个值。对吗?
  • 不,merge的返回类型是泛型的;更新的问题
  • 但是,你的其他假设是正确的

标签: typescript typescript-typings typescript-generics


【解决方案1】:

我想这样做:

type ExtractReturnTypes<T extends readonly ((i: any) => any)[]> = [
  ... {
    [K in keyof T]: T[K] extends ((i: any) => infer R) ? R : never
  }
];

function foo<I, M extends readonly ((i: I) => any)[], O>(
  input: I,
  modifiers: M,
  merge: (...args: ExtractReturnTypes<M>) => O
) {}

foo(
  1,
  [(i: number) => 5, (i: number) => 'b' as const] as const,
  // a has type: number
  // b has type: 'b'
  (a, b) => 'test'
);

【讨论】:

  • 这个怎么用?
  • 我已经编辑了我的答案,我认为它不需要像以前那样定义类型。
  • 这不起作用,因为modifier 中的每个函数都可以有不同的返回类型。我已更新问题以澄清这一点。
  • ExtractReturnTypes - 非常聪明!替代实现:type Fn = (...args: any) =&gt; any; type RT&lt;A extends ReadonlyArray&lt;Fn&gt;&gt; = A extends [infer H, ...infer R] ? H extends Fn ? R extends Fn[] ? [ReturnType&lt;H&gt;, ...RT&lt;R&gt;] : [] : [] : []
猜你喜欢
  • 1970-01-01
  • 2013-02-21
  • 2012-11-06
  • 2019-04-09
  • 2019-06-28
相关资源
最近更新 更多