Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot infer the return type of a generic function in a conditional type #58779

Closed
cshaa opened this issue Jun 5, 2024 · 2 comments
Closed
Labels
Duplicate An existing issue was already created

Comments

@cshaa
Copy link

cshaa commented Jun 5, 2024

🔎 Search Terms

Conditional type inference, generic return type, type-level lambda, higher-kinded types, mapped types

🕗 Version & Regression Information

Present in TS 3.5.1 to 5.5.0-beta.

⚪️ Introduction

I need to write a piece of code that would transverse a deeply nested data structure and fetch required data. However, I would prefer to do it in a way that doesn't force me to couple it too strongly to the data structure's specific type. This would be easiest to achieve with a generic replacer. Trying to implement it, I came across a very unintuitive behavior: given a generic function and its type parameter, it is impossible to correctly infer its return type.

💻 Code

type Foo = (<T>(input: T) => T[]) extends ((a: string) => infer R) ? R : never;
// unknown[]

⏯ Playground Link

🙁 Actual behavior

Does not infer the type argument, replaces it with unknown.

🙂 Expected behavior

Should use the inferred type argument to correctly infer the return type: string[].

Additional information about the issue

It seems to me that adding inference here would be possible – after all if I actually call the function, the type argument does get infered, and so does the return type. The doors this would open are countless, as infering the return type of a generic function is essentially higher-kinded types in a trench coat.

Were this implemented, we could do things like these:

type GenericReturnType<F extends (arg: any) => any, P> = F extends (arg: P) => infer R ? R : never;

type Box<T> = { value: T };
type Mapped<T, F extends (arg: any) => any> = { [P in keyof T]: GenericReturnType<F, T[P]> };

type Boxified<T> = Mapped<T, <V>(v: V) => Box<V>>;

(Compare #27130)

Possibly Related Issues

#57351, #33594

@fatcerberus
Copy link

fatcerberus commented Jun 5, 2024

It seems to me that adding inference here would be possible – after all if I actually call the function, the type argument does get infered, and so does the return type.

That sentence makes this a duplicate of #40179.

higher-kinded types in a trench coat

This got a chuckle out of me. 😄

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Jun 7, 2024
@typescript-bot
Copy link
Collaborator

This issue has been marked as "Duplicate" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale Jun 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants