简体   繁体   English

如何推断泛型函数的返回类型

[英]How to infer return type of a generic function

I have a function that will always return a type, though it can change and defining it by hand would be some work and not scalable, so I'm trying to achieve this by using typescript's infer keyword我有一个总是返回一个类型的函数,尽管它可以更改并且手动定义它会有些工作并且不可扩展,所以我试图通过使用 typescript 的infer关键字来实现这一点

At first I saw this reddit post that uses起初我看到这个使用的reddit帖子

type Foo<T> = T extends { a: infer U, b: infer U } ? U : never;
type T10 = Foo<{ a: string, b: string }>;  // string
type T11 = Foo<{ a: string, b: number }>;  // string | number

Problem is, my type is a generic function问题是,我的类型是一个通用函数

Here is one minimal example,这是一个最小的例子,

const fnFromLib = <T>(a: string, b: Record<string, string>) => {
  return function barFn(c: T) {
    return {
      c,
      b: b[a],
    };
  };
};
const foo = <T>(a: Record<string, string>) => {
  return {
    bar: fnFromLib<T>('foo', a),
  };
};
type returnTypeInferer<T> = T extends (a: Record<string, string>) => infer U ? U : never;
type fooType = typeof foo;
type fooReturnType = returnTypeInferer<fooType>;

there are no errors, but, since there was not a generic type being passed, fooReturnType will be inferred as没有错误,但是,由于没有传递通用类型, fooReturnType将被推断为

type fooReturnType = {
    bar: (c: unknown) => {
        c: unknown;
        b: string;
    };
}

Noting that T from fnFromLib is not inferred from arguments and should be passed in the function call I try to pass on a type argument from fooReturnType to fooType , but that gives me a parsing error注意到 fnFromLib 中的 T 不是从参数推断出来的,应该在函数调用中传递 我尝试将类型参数从fooReturnTypefooType ,但这给了我一个解析错误

type returnTypeInferer<T> = T extends (a: Record<string, string>) => infer U ? U : never;
type fooType<T> = typeof foo<T>; // ------   parsing error: ';' expected ---------
type fooReturnType<T> = returnTypeInferer<fooType<T>>;

Is there a way I can achieve what I want?有什么办法可以实现我想要的吗?

Thank you谢谢

Managed to do it by wrapping the function into a generic class设法通过将函数包装到通用类中来做到这一点

class GnClass<T> {
  foo = (a: Record<string, string>) => {
    return {
      bar: fnFromLib<T>('foo', a),
    };
  };
}
type returnTypeInferer<T> = T extends (a: Record<string, string>) => infer U ? U : never;
type fooType<T> = GnClass<T>['foo'];
type fooReturnType<T> = returnTypeInferer<fooType<T>>;

But I want to stick with functional programming, I will not mark this as accepted answer, will use it for now as I see no other alternative in the moment and would love another approach.但我想坚持使用函数式编程,我不会将其标记为已接受的答案,暂时使用它,因为我目前看不到其他选择,并且会喜欢另一种方法。

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

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