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
At first I saw this reddit post that uses
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
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
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