繁体   English   中英

Typescript - 类型 function 返回作为参数传递的每个 function 的返回值的 UNION

[英]Typescript - Type function that returns UNION of return values of each function passed as parameters

请问是否有人能够帮助我在 typescript 下面的 javascript function 中添加类型? 在最好的情况下,我想避免使用“任何”,但即使经过一整天的谷歌搜索,我也无法弄清楚这一点。

javascript 中的 Function:

function executeAll(...funcs) {
  const result = funcs.reduce((currentResult, nextFunc) => {
    return {
      ...currentResult,
      ...nextFunc(),
    };
  }, {});

  return result;
}

使用示例:

const result = executeAll(
    () => { return { firstResult: "Abc" } },
    () => { return { secondResult: 123 } });
  
console.log(result);

Function 在示例中创建 object 像这样: { firstResult: "Abc", secondResult: 123 }

基本上“executeAll”的结果应该是传入的每个 function 的返回值的 UNION。这样的事情是否可能,或者我正在尝试实现无法完成的事情?

任何帮助将非常感激。

谢谢,

米罗

您可以使用本文中概述的Spread类型以及递归类型来执行此操作:

// =========
// spread type
// =========

// Names of properties in T with types that include undefined
type OptionalPropertyNames<T> =
  { [K in keyof T]: undefined extends T[K] ? K : never }[keyof T];

// Common properties from L and R with undefined in R[K] replaced by type in L[K]
type SpreadProperties<L, R, K extends keyof L & keyof R> =
  { [P in K]: L[P] | Exclude<R[P], undefined> };

type Id<T> = {[K in keyof T]: T[K]} // see note at bottom*

// Type of { ...L, ...R }
type Spread<L, R> = Id<
  // Properties in L that don't exist in R
  & Pick<L, Exclude<keyof L, keyof R>>
  // Properties in R with types that exclude undefined
  & Pick<R, Exclude<keyof R, OptionalPropertyNames<R>>>
  // Properties in R, with types that include undefined, that don't exist in L
  & Pick<R, Exclude<OptionalPropertyNames<R>, keyof L>>
  // Properties in R, with types that include undefined, that exist in L
  & SpreadProperties<L, R, OptionalPropertyNames<R> & keyof L>
  >;

// =========
// actual type
// =========

type Func = (...args: any) => any;

type FuncMerge<T extends Func[]> =
    T extends [infer H, ...infer R]
        ? H extends Func ? R extends Func[]
            ? Spread<ReturnType<H>, FuncMerge<R>>
            : never : never
        : {};

function executeAll<T extends Func[]>(...funcs: T): FuncMerge<T> {
  const result = funcs.reduce((currentResult, nextFunc) => {
    return {
      ...currentResult,
      ...nextFunc(),
    };
  }, {});

  return result as FuncMerge<T>;
}

const result = executeAll(
    () => { return { firstResult: "Abc" } },
    () => { return { secondResult: 123 } });

type Foo = typeof result;

游乐场链接

暂无
暂无

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

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