Skip to content

Infer return type of a function with provided argument types #26043

Closed

Description

@int0h

I'm trying to create something similar to native ReturnType type. In comparison to the later, it should also consider generic types of arguments.

I guess the idea will be clear from the code below.

If it can be done now - I'd be happy to receive some links. Otherways it'd be great to know if there are any plans to cover that behavior. In case it could be achieved by another not-implemented feature I'll be glad for the link to an issue to be able to track its progress.

TypeScript Version: 2.9.2

Search Terms: infer function return type

Code

// it works with actual code:
function identity<T>(a: T) {
    return a;
}

const one = identity(1); // typeof one === 1 # everything is great

function call<A, R>(arg: A, fn: Func<A, R>): R {
    return fn(arg);
}

const two = call(2 as 2, i => i) // typeof two === 2 # everything is great

// but won't work with types
type Func<A, R> = (arg: A) => R;
// ReturnTypeByArg is inspired by `ReturnType` from TS 2.8.*
type ReturnTypeByArg<T, F extends Func<T, any>> = F extends Func<T, infer R> ? R : any;

type Identity = <T>(a: T) => T;
type Result = ReturnTypeByArg<4, Identity>; // Result === {} # not what I expect

Expected behavior:
I expect TS to be able to infer such return type

Actual behavior:
Return type is {}

Playground Link: link

Related Issues:

Activity

  1. mhegazy commented on Jul 30, 2018

    @mhegazy
    Contributor

    Looks like a duplicate of #6606

  2. int0h commented on Jul 31, 2018

    @int0h
    Author

    Mohamed Hegazy (@mhegazy) I guess #6606 is a much more complex feature request. Mine looks like only one case of "Call" type which was referenced by Trey Brisbane (@treybrisbane). And if such Call type is implemented it will cover my issue also.

    But I thought my problem can be solved through new 2.8.* infer key-word. So I see it rather as a bug than a feature request.

    It would be great if you provided me with a link to an issue about such Call type if one exists.

    By the way, since #6606 is closed I'm not sure what do you mean by marking mine as a duplicate. Does it mean this issue won't be fixed?

  3. mhegazy commented on Jul 31, 2018

    @mhegazy
    Contributor

    The underlying scenario is the same. #6606 proposed using typeof as syntax, but you can see the same happening using a call syntax foo(number, string) without the typeof keyword.

    The complexity in implementing either is applying overload resolution as a higher-order type operator. the overload resolution is extremely complicated process, that involved multiple passes and required multiple processes like contextual types, inference, and instantiations to interact. Enabling this, at least in the current compiler implementation, for higher order types is tantamount to rewriting the core of the compiler; something we are not looking forward to.

    You can seem my reply in #6606 (comment) as well.

  4. malash commented on Dec 14, 2018

    @malash

    I believe that's not a bug.

    infer R is the union of all available types.

    const f1: Func<4, 4> = identity;
    // @ts-ignore f2 failed
    const f2: Func<4, 1> = identity;
    const f3: Func<4, number> = identity;
    const f4: Func<4, any> = identity;
    const f5: Func<4, {}> = identity;

    As you can see the second argument of Func could be any, as known as {}.

    So infer R should be union of them and it's {}.

    For a given infer type variable V, if any candidates were inferred from co-variant positions, the type inferred for V is a union of those candidates. https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html

    int0h

  5. typescript-bot commented on Dec 16, 2018

    @typescript-bot
    Contributor

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

  6. locked as resolved and limited conversation to collaborators on Oct 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions