简体   繁体   English

Typescript function 作为参数 - 使用输入的 ZDBC11CAA5BDA28F77E6FB4EDABD8 推断 output 类型

[英]Typescript function as argument - infer output type using inputted arguments

I have a hook that takes in a function as an argument, and returns another function.我有一个钩子,它接受 function 作为参数,并返回另一个 function。 The output function has identical arguments to the inputted function. output function 具有与输入的 ZC1C425268E68385D1AB5074C17A 相同的 arguments。 Only the return type differs.只有返回类型不同。

type InputFn = (...args: any[]) => Promise<string>
type OutputFn<TInput> = (args: Parameters<TInput>) => void

useDemo<TInput extends InputFn>(input: TInput): OutputFn {
   const output = useCallback((...args) => {
     input(args).then(str => doSomeStuff())
   }, 
   [])

   return output
}

I would like the output to be typed based on the input.我希望根据输入键入 output。 eg例如

  const output = useDemo((a: string, b: number) => Promise.resolve(''))
  // Output Type: (a: string, b: number) => void

How can I achieve this?我怎样才能做到这一点? I currently only get any[] type and a lot of errors.我目前只得到任何 [] 类型和很多错误。

You're right to use the Parameters utility type , but you want to use it in the return type declaration referring to the generic type parameter TInput , rather than outside it as a type declaration:您使用Parameters实用程序 type是正确的,但您希望在引用泛型类型参数TInput的返回类型声明中使用它,而不是在它之外作为类型声明:

function useDemo<TInput extends InputFn>(input: TInput): (...params: Parameters<TInput>) => void {
    return function(...args: Parameters<TInput>): void {
        input().then(str => { /*...*/ }); // Really need a `catch` on this! :-)
    };
}

Then for example:然后例如:

const output1 = useDemo((x: string, y: number) => Promise.resolve(""));
//    ^−−− type is `(x: string, y: number) => void`
const output2 = useDemo((x: string) => Promise.resolve(""));
//    ^−−− type is `(x: string) => void`

Playground link 游乐场链接

Or if you want to declare it separately, you can do that, but it has to be a generic type so you can pass in the resolved type of the generic argument to useDemo :或者,如果您想单独声明它,您可以这样做,但它必须是泛型类型,以便您可以将泛型参数的解析类型传递给useDemo

type InputFn = (...args: any[]) => Promise<string>;
type OutputFn<TInput extends InputFn> = (...params: Parameters<TInput>) => void;

function useDemo<TInput extends InputFn>(input: TInput): OutputFn<TInput> {
    return function(...args: Parameters<TInput>): void {
        input().then(str => { /*...*/ }); // Really need a `catch` on this! :-)
    };
}

Playground link 游乐场链接

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

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