【问题标题】:create generic type from generic function从泛型函数创建泛型类型
【发布时间】:2019-12-27 00:38:54
【问题描述】:

我正在尝试基于另一个泛型类型声明一个泛型类型,但没有成功。

目标是编写我自己的测试框架并根据另一个(方法)键入一些参数。

type Arguments<T> = T extends (...args: infer U) => any ? U : never;

// my custom test method
const methodCall = <T extends (...args: any) => any>(args: {
  method: T;
  response: ReturnType<T>;
  myArguments: Arguments<T>;
}): boolean => {
  const { method, myArguments, response } = args;
  return method.apply(null, myArguments) === response;
};

const test1 = (toto: string) => {
  return toto === "success";
};

// usage of my custom function
methodCall({
  method: test1,
  myArguments: ["fail"],
  response: false
});


// this is what I want to type
interface MyHelpers {
  methodCall: any // HOW TO TYPE THIS? 
  methodCall2: (args: { flag: boolean }) => boolean;
}

// I would expose only the helpers object
const helpers = (): MyHelpers = {
  methodCall: <T extends (...args: any) => any>(args: {
    method: T;
    response: ReturnType<T>;
    myArguments: Arguments<T>;
  }): boolean => {
    const { method, myArguments, response } = args;
    return method.apply(null, myArguments) === response;
  },
  methodCall2: (args: { flag: boolean }): boolean => {
    return args.flag;
  }
};

我期望另一个调用助手的对象能够使用 helpers().methodCall(...) 来键入,因为它在助手中声明。不是any

操场可以在here 找到。

谢谢!

【问题讨论】:

    标签: typescript typescript-typings typescript-generics


    【解决方案1】:

    如果我理解正确的话,你已经很接近了。您可以在函数语法(定义methodCall 的签名,就像定义函数实现一样)和属性语法(将methodCall 定义为恰好是lambda 的属性,接近于你是怎么得到它的)。

    如果使用函数语法,则定义尖括号中的泛型 (&lt;&gt;)、括号之间的参数列表以及冒号后的返回类型;就好像您正在定义一个没有主体的函数。如果您使用属性语法,您将定义一个 lambda,尖括号中的泛型、括号之间的参数列表以及 粗箭头后的返回类型 (=&gt;);您正在使用该名称定义一个属性,并将您的类型—a function type—放在冒号之后。无论哪种方式都适合你。

    (我还从您的自定义 Arguments 实用程序类型切换到 the undocumented Parameters built-in。)

    interface MyHelpers {
      methodCall<T extends (...args: any) => any>(args: {
        method: T;
        response: ReturnType<T>;
        myArguments: Parameters<T>;
      }): boolean;
      methodCall2: (args: { flag: boolean }) => boolean;
    }
    
    interface MyHelpersWithObjectSyntax {
      methodCall: <T extends (...args: any) => any>(args: {
        method: T;
        response: ReturnType<T>;
        myArguments: Parameters<T>;
      }) => boolean;
      methodCall2: (args: { flag: boolean }) => boolean;
    }
    

    typescript playground

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-29
      • 1970-01-01
      相关资源
      最近更新 更多