Skip to content

Generic type defaulting to {} instead of any #7505

Closed

Description

@robianmcd

TypeScript Version:
1.7.3

Code

window['test'] = {a:1, b:2};

function myFunc<T>(): T
{
    return window['test'];
}

let test = myFunc();
console.log(test.a);

Expected behavior:
The type of test is any so there is no compiler error.

Actual behavior:
I get the following error message
myFile.ts(9,18): error TS2339: Property 'a' does not exist on type '{}'.

Use Case
I run into this issue whenever I'm working on an Angular project and using the $http service. The type definition for $http.get() is as follows

get<T>(url: string, config?: IRequestShortcutConfig): IHttpPromise<T>;

so if you don't explicitly specify what T is you get an error when you try to access the response.

Activity

  1. sandersn commented on Mar 14, 2016

    @sandersn
    Member

    myFunc (and $http.get, it looks like) doesn't have any arguments to infer T from. So type inference will end up assigning the type {} if it's not specified. This behaviour is by design.

    I don't think there's any alternative to specifying the type you're getting from $http.get. TypeScript doesn't infer types from later usage of test, for example.

  2. robianmcd commented on Mar 14, 2016

    @robianmcd
    Author

    When you don't specify a type everywhere else in TypeScript the type defaults to any so this behavior seems counter intuitive to me. But yeah I can just specify the type to workaround it.

  3. mhegazy commented on Mar 14, 2016

    @mhegazy
    Contributor

    #6354 would be a better solution here.

  4. mhegazy commented on Mar 14, 2016

    @mhegazy
    Contributor

    also, you can achieve the same result today by defining an overload.

    function myFunc(): any;
    function myFunc<T>(): T;
    function myFunc(): any {
        return window['test'];
    }
  5. sandersn commented on Mar 14, 2016

    @sandersn
    Member

    Rob (@robianmcd) I think it's because "T" inside of a function acts like {} -- you can't see any properties on it, for example. So if you return T, and the compiler never inferred any actual type for it, it sort of makes sense that it comes out as {}.

    Also, unlike the other cases where there is no type specified, there is a type variable here -- T -- which the compiler infers a type for. {} indicates failure rather than any. any would be easier to use, though.

  6. robianmcd commented on Mar 14, 2016

    @robianmcd
    Author

    Mohamed Hegazy (@mhegazy) yeah the issue you linked to would be a good solution. Also I didn't think of overloading the function like that. thanks

  7. locked and limited conversation to collaborators on Jun 19, 2018
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

    By DesignDeprecated - use "Working as Intended" or "Design Limitation" instead

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions