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

Strange this parameter behaviour #9648

Closed
olmobrutall opened this issue Jul 12, 2016 · 3 comments
Closed

Strange this parameter behaviour #9648

olmobrutall opened this issue Jul 12, 2016 · 3 comments
Labels
Fixed A PR has been merged for this issue

Comments

@olmobrutall
Copy link

TypeScript Version: 2.0.0 beta with "noImplicitThis": true

Code

interface String {
     contains(this: string, str: string): boolean;
}

 // OK
String.prototype.contains = function (this: string, str: string): boolean { 
    return this.indexOf(element) != -1;
};

//Error: 'this' implicitly has type 'any' because it does not have a type annotation.   
String.prototype.contains = function (str: string) {
    return this.indexOf(str) != -1;
};

// OK
String.prototype.contains = function (str): boolean { 
    return this.indexOf(str) != -1;
};

// OK
String.prototype.contains = function (str) { 
    return this.indexOf(str) != -1;
};

Look like once you type some parameters you have to type all of them, including the this.

What's the reason?

@mhegazy
Copy link
Contributor

mhegazy commented Jul 12, 2016

//cc @sandersn

@sandersn
Copy link
Member

sandersn commented Jul 12, 2016

The problem is that it's confusing when contextual typing applies or doesn't apply. Let's look at your examples in order:

  1. Typed parameter, explicit this

    String.prototype.contains = function (this: string, str: string) ...

    This is OK because you explicitly give this a type. No contextual typing happens here.

  2. Typed parameter, no this

    String.prototype.contains = function (str: string) ...

    This is not OK because you give str a type. This disables contextual typing, meaning that this doesn't get the contextual type from your String definition. So it becomes any, which triggers --noImplicitThis.

  3. Untyped parameter, explicit return

    String.prototype.contains = function(str) ...

    This is OK because str doesn't have a type. Contextual typing works now, and pulls in string for the type of str as well as string for the type of this.

  4. Untyped parameter, no return

    This is the same as (3). Return types do not affect whether a function expression is contextually typed.

Overall, the system is behaving as expected. I'd recommend dropping all type annotations and letting contextual typing and return type inference take care of it. However, the existing string methods should also have this annotated, just like your polyfill. I'll create a separate issue for that.

@sandersn sandersn added the Working as Intended The behavior described is the intended behavior; this is not a bug label Jul 12, 2016
@mhegazy
Copy link
Contributor

mhegazy commented Jul 12, 2016

#4241 is tracking changing this behavior so that one argument type annotation does not block inference for the rest unannotated ones.

@ahejlsberg ahejlsberg added the Fixed A PR has been merged for this issue label Oct 18, 2016
@mhegazy mhegazy removed the Working as Intended The behavior described is the intended behavior; this is not a bug label Oct 18, 2016
@mhegazy mhegazy added this to the TypeScript 2.1 milestone Oct 18, 2016
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Fixed A PR has been merged for this issue
Projects
None yet
Development

No branches or pull requests

4 participants