Skip to content

Type inference error with method generic 'this' typing #10468

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

Closed
HerringtonDarkholme opened this issue Aug 22, 2016 · 5 comments
Closed

Type inference error with method generic 'this' typing #10468

HerringtonDarkholme opened this issue Aug 22, 2016 · 5 comments
Assignees
Labels
Fixed A PR has been merged for this issue

Comments

@HerringtonDarkholme
Copy link
Contributor

HerringtonDarkholme commented Aug 22, 2016

Sorry for the undescriptive title but the behavior is too strange for me to describe...

Related to #9673 and #9746 with subtle difference

Maybe it's still problem for instantiating this? @sandersn

TypeScript Version: 2.0.0

Code

Declaration

// A *self-contained* demonstration of the problem follows...
declare class VueTyped<T> {
  data<D>(d: D): VueTyped<T & D>;
  method<M extends { [k:string]: (this: T) => ({} | void) }>(m: M): VueTyped<T & M>
  static init(): VueTyped<{}>
}

Usage:

When under --noImplicitThis flag, this code reports this has implicit any.
No error when implictThis is allowed.

VueTyped.init()
  .data({msg: '123'})
  .method({
    method() {
      this.msgs.length // error here but reported wrongly
      return this.msg 
    }
  })

Another usage:
When return value isn't from this, compiler has a false alarm.

VueTyped.init()
  .data({msg: '123'})
  .method({
    method() {
      this.msg // error her but should not
      return '123'
    }
  })

Expected behavior:
For the first usage, this.msgs should trigger Property not exist error.
For the second usage, this.msg should not report any error.

Actual behavior:

No implicit this errors for both.

@sandersn
Copy link
Member

Shouldn't the second example trigger the error "'msg' does not exist"? As far as I can tell, this: T and T = {} based on the call to VueTyped.init(): VueTyped<{}>

@sandersn
Copy link
Member

Never mind, I didn't see that the definition of data: VueTyped<T & D>.

Without --noImplicitThis, I don't get an error for either case. With --noImplicitThis, I get two "this is implicitly any" errors. That's because there is no contextual this-typing happening at all. I think it's because methods aren't aware of the signature that should be coming from the string index.

@sandersn
Copy link
Member

Here's a simplified repro. I'm going to see if #9746 fixes this.

declare function infer<T, M extends { [k:string]: (this: T, hunch: T) => ({} | void) }>(t: T, m: M): void;
infer({msg: '123'}, {
  method() {
    this.msg // error her but should not
    return '123'
  }
})
infer({msg: '123'}, {
  method(hunch) {
    this.msgs.length // error here but reported wrongly
    return this.msg // shouldn't error here either
  }
})

@sandersn
Copy link
Member

Yes, this is fixed by #9746

@sandersn sandersn self-assigned this Aug 22, 2016
@mhegazy mhegazy added the Fixed A PR has been merged for this issue label Aug 22, 2016
@mhegazy mhegazy added this to the TypeScript 2.0.1 milestone Aug 22, 2016
@mhegazy mhegazy closed this as completed Aug 22, 2016
@HerringtonDarkholme
Copy link
Contributor Author

Thanks! Going to try this in nightly. TypeScript is just so awesome!

@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

3 participants